Skip to content

Commit 3a00948

Browse files
chore: Move what-is-circular dep within Cypress repo (#29530)
* chore: Move what-is-circular dep within Cypress repo * empty commit * Fix ts issue in what-is-circular
1 parent 5a23501 commit 3a00948

File tree

6 files changed

+220
-16
lines changed

6 files changed

+220
-16
lines changed
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
import { whatIsCircular } from '../../../src/util/what-is-circular'
2+
3+
describe('what-is-circular', function () {
4+
it('should return undefined if passed a non-object', function () {
5+
expect(whatIsCircular(2)).to.eq(undefined)
6+
})
7+
8+
it('should return path for circular objects', function () {
9+
const x: any = {}
10+
11+
x.cyclic = { a: 1, x }
12+
expect(whatIsCircular(x)).to.deep.eq(['cyclic', 'x'])
13+
})
14+
15+
it('should return path for circular objects', function () {
16+
const x: any = {}
17+
18+
x.cyclic = { a: {}, x }
19+
expect(whatIsCircular(x)).to.deep.eq(['cyclic', 'x'])
20+
})
21+
22+
it('should return path for circular objects', function () {
23+
const x: any = {}
24+
25+
x.cyclic = { a: {}, indirect: { x } }
26+
expect(whatIsCircular(x)).to.deep.eq(['cyclic', 'indirect', 'x'])
27+
})
28+
29+
it('should return path for circular objects', function () {
30+
const a = {
31+
a: false,
32+
b: {
33+
a: false,
34+
c: {
35+
a: false,
36+
d: {
37+
e: {
38+
a: false,
39+
},
40+
},
41+
},
42+
},
43+
}
44+
45+
a.b.c.d.e = a
46+
47+
expect(whatIsCircular(a)).to.deep.eq(['b', 'c', 'd', 'e'])
48+
})
49+
50+
it('should return path for circular objects', function () {
51+
const x: any = {
52+
a: [
53+
{
54+
a: 'b',
55+
b: 'c',
56+
},
57+
{
58+
a: 'b',
59+
b: 'c',
60+
},
61+
],
62+
b: [
63+
'a',
64+
'b',
65+
],
66+
}
67+
68+
x.c = {
69+
x,
70+
}
71+
72+
expect(whatIsCircular(x)).to.deep.eq(['c', 'x'])
73+
})
74+
75+
it('should return path for circular objects in arrays', function () {
76+
const x: any = {
77+
a: [
78+
{
79+
a: 'b',
80+
b: 'c',
81+
},
82+
{
83+
a: 'b',
84+
b: 'c',
85+
},
86+
],
87+
b: [
88+
'a',
89+
'b',
90+
],
91+
}
92+
93+
x.a[2] = x
94+
95+
expect(whatIsCircular(x)).to.deep.eq(['a', '2'])
96+
})
97+
98+
it('should return undefined for non-circular objects', function () {
99+
const x: any = {}
100+
101+
x.cyclic = { a: 1, b: 2 }
102+
expect(whatIsCircular(x)).to.eq(undefined)
103+
})
104+
105+
it('should return undefined for non-circular objects', function () {
106+
const x: any = {
107+
a: [
108+
{
109+
a: 'b',
110+
b: 'c',
111+
},
112+
{
113+
a: 'b',
114+
b: 'c',
115+
},
116+
],
117+
b: [
118+
'a',
119+
'b',
120+
],
121+
}
122+
123+
expect(whatIsCircular(x)).to.eq(undefined)
124+
})
125+
126+
it('should return undefined for non-circular objects', function () {
127+
const x: any = {}
128+
const y = {}
129+
130+
x.cyclic = { a: y, b: y }
131+
expect(whatIsCircular(x)).to.eq(undefined)
132+
})
133+
134+
it('detects circular objects and returns path', function () {
135+
const obj1: any = {}
136+
137+
obj1.x = obj1
138+
expect(whatIsCircular(obj1)).to.deep.eq(['x'])
139+
140+
const obj2: any = {}
141+
142+
obj2.x = { y: obj2 }
143+
expect(whatIsCircular(obj2)).to.deep.eq(['x', 'y'])
144+
})
145+
146+
it('detects circular arrays and returns path', function () {
147+
const obj1: any = []
148+
149+
obj1.push(obj1)
150+
expect(whatIsCircular(obj1)).to.deep.eq(['0'])
151+
})
152+
153+
it('detects non-circular objects and returns undefined', function () {
154+
const obj1: any = {}
155+
156+
obj1.x = { y: 4 }
157+
expect(whatIsCircular(obj1)).to.be.undefined
158+
159+
expect(whatIsCircular({})).to.be.undefined
160+
})
161+
162+
it('detects non-circular arrays and returns undefined', function () {
163+
const obj1: any[] = []
164+
165+
obj1.push([])
166+
expect(whatIsCircular(obj1)).to.be.undefined
167+
})
168+
169+
it('returns undefined for non-objects', function () {
170+
expect(whatIsCircular(undefined)).to.be.undefined
171+
expect(whatIsCircular(null)).to.be.undefined
172+
expect(whatIsCircular('hi')).to.be.undefined
173+
expect(whatIsCircular(false)).to.be.undefined
174+
expect(whatIsCircular(/a/)).to.be.undefined
175+
})
176+
177+
it('returns undefined for non-circular functions', function () {
178+
expect(whatIsCircular(function () {})).to.be.undefined
179+
})
180+
181+
it('returns path for circular functions', function () {
182+
const f: any = function () {}
183+
184+
f.x = {
185+
y: {
186+
f,
187+
},
188+
}
189+
190+
expect(whatIsCircular(f)).to.deep.eq(['x', 'y', 'f'])
191+
})
192+
})

packages/driver/package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
"@cypress/unique-selector": "0.0.5",
1919
"@cypress/webpack-dev-server": "0.0.0-development",
2020
"@cypress/webpack-preprocessor": "0.0.0-development",
21-
"@cypress/what-is-circular": "1.0.1",
2221
"@medv/finder": "3.1.0",
2322
"@packages/config": "0.0.0-development",
2423
"@packages/network": "0.0.0-development",

packages/driver/src/cy/commands/navigation.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import _ from 'lodash'
2-
import whatIsCircular from '@cypress/what-is-circular'
32
import UrlParse from 'url-parse'
43
import Promise from 'bluebird'
54

@@ -9,6 +8,7 @@ import { LogUtils, Log } from '../../cypress/log'
98
import { bothUrlsMatchAndOneHasHash } from '../navigation'
109
import { $Location, LocationObject } from '../../cypress/location'
1110
import { isRunnerAbleToCommunicateWithAut } from '../../util/commandAUTCommunication'
11+
import { whatIsCircular } from '../../util/what-is-circular'
1212

1313
import type { RunState } from '@packages/types'
1414

packages/driver/src/cy/commands/request.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import _ from 'lodash'
2-
import whatIsCircular from '@cypress/what-is-circular'
32
import Promise from 'bluebird'
43

54
import $utils from '../../cypress/utils'
65
import $errUtils from '../../cypress/error_utils'
76
import { $Location } from '../../cypress/location'
7+
import { whatIsCircular } from '../../util/what-is-circular'
88

99
const isOptional = (memo, val, key) => {
1010
if (_.isNull(val)) {
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
const lodash = require('lodash')
2+
3+
export function whatIsCircular (obj) {
4+
if (!lodash.isObject(obj)) {
5+
return
6+
}
7+
8+
return _dfs(obj)
9+
}
10+
11+
function _dfs (obj, parents: any[] = [], parentKeys: any[] = []) {
12+
// recurse depth-first until we hit something we've seen before
13+
for (const key in obj) {
14+
const val = obj[key]
15+
16+
if (lodash.isObject(val)) {
17+
if (lodash.includes(parents, val)) {
18+
return parentKeys
19+
}
20+
21+
const path = _dfs(val, parents.concat([val]), parentKeys.concat([key]))
22+
23+
if (path) return path
24+
}
25+
}
26+
}

yarn.lock

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3069,14 +3069,6 @@
30693069
dependencies:
30703070
css.escape "^1.5.1"
30713071

3072-
"@cypress/[email protected]":
3073-
version "1.0.1"
3074-
resolved "https://registry.yarnpkg.com/@cypress/what-is-circular/-/what-is-circular-1.0.1.tgz#c88adb7106a4e1624e403512fc87c18e9700c877"
3075-
integrity sha512-AZP6hxdiXhVKSdTeIb8tBkotH5sq/MEvECk4byAF44ulPL7MXvhInRthof20cK3UDAycKo0ThJvT71mhSfsOPw==
3076-
dependencies:
3077-
lodash.includes "^4.3.0"
3078-
lodash.isobject "^3.0.2"
3079-
30803072
"@cypress/xvfb@^1.2.4":
30813073
version "1.2.4"
30823074
resolved "https://registry.yarnpkg.com/@cypress/xvfb/-/xvfb-1.2.4.tgz#2daf42e8275b39f4aa53c14214e557bd14e7748a"
@@ -20977,11 +20969,6 @@ lodash.isnumber@^3.0.3:
2097720969
resolved "https://registry.yarnpkg.com/lodash.isnumber/-/lodash.isnumber-3.0.3.tgz#3ce76810c5928d03352301ac287317f11c0b1ffc"
2097820970
integrity sha1-POdoEMWSjQM1IwGsKHMX8RwLH/w=
2097920971

20980-
lodash.isobject@^3.0.2:
20981-
version "3.0.2"
20982-
resolved "https://registry.yarnpkg.com/lodash.isobject/-/lodash.isobject-3.0.2.tgz#3c8fb8d5b5bf4bf90ae06e14f2a530a4ed935e1d"
20983-
integrity sha1-PI+41bW/S/kK4G4U8qUwpO2TXh0=
20984-
2098520972
[email protected], lodash.isplainobject@^4.0.6:
2098620973
version "4.0.6"
2098720974
resolved "https://registry.yarnpkg.com/lodash.isplainobject/-/lodash.isplainobject-4.0.6.tgz#7c526a52d89b45c45cc690b88163be0497f550cb"

0 commit comments

Comments
 (0)