@vltpkg/query 1.0.0-rc.32 → 1.0.0-rc.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +10 -6
- package/dist/parser.js +2 -1
- package/dist/pseudo/hostname.js +3 -1
- package/dist/pseudo/malware.d.ts +3 -16
- package/dist/pseudo/malware.js +11 -171
- package/dist/pseudo/scripts.js +1 -1
- package/dist/pseudo/vuln.d.ts +22 -0
- package/dist/pseudo/vuln.js +220 -0
- package/dist/pseudo.js +3 -3
- package/dist/types.d.ts +3 -2
- package/package.json +19 -10
- package/skills/dss-query/REFERENCE.md +123 -0
- package/skills/dss-query/SKILL.md +190 -0
- package/skills/dss-query/evals/README.md +79 -0
- package/skills/dss-query/evals/evals.json +89 -0
- package/skills/dss-query/evals/grade.mjs +480 -0
- package/src/attribute.ts +186 -0
- package/src/combinator.ts +132 -0
- package/src/id.ts +46 -0
- package/src/index.ts +620 -0
- package/src/parser.ts +122 -0
- package/src/pseudo/abandoned.ts +9 -0
- package/src/pseudo/attr.ts +92 -0
- package/src/pseudo/built.ts +19 -0
- package/src/pseudo/confused.ts +29 -0
- package/src/pseudo/cve.ts +93 -0
- package/src/pseudo/cwe.ts +97 -0
- package/src/pseudo/debug.ts +9 -0
- package/src/pseudo/deprecated.ts +9 -0
- package/src/pseudo/dev.ts +18 -0
- package/src/pseudo/diff.ts +90 -0
- package/src/pseudo/dist.ts +144 -0
- package/src/pseudo/dynamic.ts +9 -0
- package/src/pseudo/empty.ts +15 -0
- package/src/pseudo/entropic.ts +9 -0
- package/src/pseudo/env.ts +6 -0
- package/src/pseudo/eval.ts +9 -0
- package/src/pseudo/fs.ts +9 -0
- package/src/pseudo/helpers.ts +106 -0
- package/src/pseudo/host.ts +111 -0
- package/src/pseudo/hostname.ts +156 -0
- package/src/pseudo/license.ts +134 -0
- package/src/pseudo/link.ts +30 -0
- package/src/pseudo/malware.ts +41 -0
- package/src/pseudo/minified.ts +9 -0
- package/src/pseudo/missing.ts +16 -0
- package/src/pseudo/native.ts +9 -0
- package/src/pseudo/network.ts +9 -0
- package/src/pseudo/obfuscated.ts +9 -0
- package/src/pseudo/optional.ts +18 -0
- package/src/pseudo/outdated.ts +305 -0
- package/src/pseudo/overridden.ts +20 -0
- package/src/pseudo/path.ts +146 -0
- package/src/pseudo/peer.ts +18 -0
- package/src/pseudo/prerelease.ts +47 -0
- package/src/pseudo/private.ts +19 -0
- package/src/pseudo/prod.ts +18 -0
- package/src/pseudo/published.ts +248 -0
- package/src/pseudo/registry.ts +29 -0
- package/src/pseudo/root.ts +19 -0
- package/src/pseudo/scanned.ts +20 -0
- package/src/pseudo/score.ts +186 -0
- package/src/pseudo/scripts.ts +54 -0
- package/src/pseudo/semver.ts +320 -0
- package/src/pseudo/severity.ts +231 -0
- package/src/pseudo/shell.ts +9 -0
- package/src/pseudo/shrinkwrap.ts +9 -0
- package/src/pseudo/spec.ts +131 -0
- package/src/pseudo/squat.ts +225 -0
- package/src/pseudo/suspicious.ts +9 -0
- package/src/pseudo/tracker.ts +9 -0
- package/src/pseudo/trivial.ts +9 -0
- package/src/pseudo/type.ts +26 -0
- package/src/pseudo/undesirable.ts +9 -0
- package/src/pseudo/unknown.ts +9 -0
- package/src/pseudo/unmaintained.ts +9 -0
- package/src/pseudo/unpopular.ts +9 -0
- package/src/pseudo/unstable.ts +9 -0
- package/src/pseudo/vuln.ts +273 -0
- package/src/pseudo/workspace.ts +22 -0
- package/src/pseudo.ts +413 -0
- package/src/types.ts +165 -0
- package/tap-snapshots/test/attribute.ts.test.cjs +304 -0
- package/tap-snapshots/test/combinator.ts.test.cjs +333 -0
- package/tap-snapshots/test/id.ts.test.cjs +118 -0
- package/tap-snapshots/test/parser.ts.test.cjs +344 -0
- package/tap-snapshots/test/pseudo/abandoned.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/attr.ts.test.cjs +161 -0
- package/tap-snapshots/test/pseudo/built.ts.test.cjs +70 -0
- package/tap-snapshots/test/pseudo/confused.ts.test.cjs +32 -0
- package/tap-snapshots/test/pseudo/cve.ts.test.cjs +49 -0
- package/tap-snapshots/test/pseudo/cwe.ts.test.cjs +49 -0
- package/tap-snapshots/test/pseudo/debug.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/deprecated.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/dist.ts.test.cjs +30 -0
- package/tap-snapshots/test/pseudo/dynamic.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/empty.ts.test.cjs +50 -0
- package/tap-snapshots/test/pseudo/entropic.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/env.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/eval.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/fs.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/helpers.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/hostname.ts.test.cjs +148 -0
- package/tap-snapshots/test/pseudo/license.ts.test.cjs +41 -0
- package/tap-snapshots/test/pseudo/link.ts.test.cjs +36 -0
- package/tap-snapshots/test/pseudo/malware.ts.test.cjs +22 -0
- package/tap-snapshots/test/pseudo/minified.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/missing.ts.test.cjs +30 -0
- package/tap-snapshots/test/pseudo/native.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/network.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/obfuscated.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/outdated.ts.test.cjs +130 -0
- package/tap-snapshots/test/pseudo/overridden.ts.test.cjs +75 -0
- package/tap-snapshots/test/pseudo/prerelease.ts.test.cjs +101 -0
- package/tap-snapshots/test/pseudo/private.ts.test.cjs +38 -0
- package/tap-snapshots/test/pseudo/published.ts.test.cjs +171 -0
- package/tap-snapshots/test/pseudo/registry.ts.test.cjs +68 -0
- package/tap-snapshots/test/pseudo/root.ts.test.cjs +24 -0
- package/tap-snapshots/test/pseudo/scanned.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/score.ts.test.cjs +239 -0
- package/tap-snapshots/test/pseudo/scripts.ts.test.cjs +61 -0
- package/tap-snapshots/test/pseudo/semver.ts.test.cjs +575 -0
- package/tap-snapshots/test/pseudo/severity.ts.test.cjs +95 -0
- package/tap-snapshots/test/pseudo/shell.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/shrinkwrap.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/spec.ts.test.cjs +148 -0
- package/tap-snapshots/test/pseudo/squat.ts.test.cjs +129 -0
- package/tap-snapshots/test/pseudo/suspicious.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/tracker.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/trivial.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/type.ts.test.cjs +51 -0
- package/tap-snapshots/test/pseudo/undesirable.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/unknown.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/unmaintained.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/unpopular.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/unstable.ts.test.cjs +18 -0
- package/tap-snapshots/test/pseudo/vuln.ts.test.cjs +208 -0
- package/tap-snapshots/test/pseudo/vulnerable.ts.test.cjs +20 -0
- package/tap-snapshots/test/pseudo/workspace.ts.test.cjs +19 -0
- package/tap-snapshots/test/pseudo.ts.test.cjs +1247 -0
- package/test/attribute.ts +266 -0
- package/test/combinator.ts +168 -0
- package/test/fixtures/graph.ts +999 -0
- package/test/fixtures/selector.ts +103 -0
- package/test/fixtures/types.ts +7 -0
- package/test/id.ts +102 -0
- package/test/index.ts +1000 -0
- package/test/parser.ts +117 -0
- package/test/pseudo/abandoned.ts +98 -0
- package/test/pseudo/attr.ts +298 -0
- package/test/pseudo/built.ts +214 -0
- package/test/pseudo/confused.ts +160 -0
- package/test/pseudo/cve.ts +249 -0
- package/test/pseudo/cwe.ts +255 -0
- package/test/pseudo/debug.ts +98 -0
- package/test/pseudo/deprecated.ts +98 -0
- package/test/pseudo/dev.ts +61 -0
- package/test/pseudo/diff.ts +417 -0
- package/test/pseudo/dist.ts +215 -0
- package/test/pseudo/dynamic.ts +98 -0
- package/test/pseudo/empty.ts +108 -0
- package/test/pseudo/entropic.ts +101 -0
- package/test/pseudo/env.ts +98 -0
- package/test/pseudo/eval.ts +98 -0
- package/test/pseudo/fs.ts +98 -0
- package/test/pseudo/helpers.ts +370 -0
- package/test/pseudo/host-context.ts +276 -0
- package/test/pseudo/hostname.ts +314 -0
- package/test/pseudo/license.ts +265 -0
- package/test/pseudo/link.ts +94 -0
- package/test/pseudo/malware.ts +184 -0
- package/test/pseudo/minified.ts +98 -0
- package/test/pseudo/missing.ts +111 -0
- package/test/pseudo/native.ts +98 -0
- package/test/pseudo/network.ts +98 -0
- package/test/pseudo/obfuscated.ts +98 -0
- package/test/pseudo/optional.ts +73 -0
- package/test/pseudo/outdated.ts +331 -0
- package/test/pseudo/overridden.ts +317 -0
- package/test/pseudo/path.ts +680 -0
- package/test/pseudo/peer.ts +101 -0
- package/test/pseudo/prerelease.ts +279 -0
- package/test/pseudo/private.ts +108 -0
- package/test/pseudo/prod.ts +61 -0
- package/test/pseudo/published.ts +557 -0
- package/test/pseudo/registry.ts +122 -0
- package/test/pseudo/root.ts +66 -0
- package/test/pseudo/scanned.ts +78 -0
- package/test/pseudo/score.ts +591 -0
- package/test/pseudo/scripts.ts +294 -0
- package/test/pseudo/semver.ts +822 -0
- package/test/pseudo/severity.ts +310 -0
- package/test/pseudo/shell.ts +98 -0
- package/test/pseudo/shrinkwrap.ts +98 -0
- package/test/pseudo/spec.ts +525 -0
- package/test/pseudo/squat.ts +565 -0
- package/test/pseudo/suspicious.ts +98 -0
- package/test/pseudo/tracker.ts +98 -0
- package/test/pseudo/trivial.ts +98 -0
- package/test/pseudo/type.ts +105 -0
- package/test/pseudo/undesirable.ts +98 -0
- package/test/pseudo/unknown.ts +98 -0
- package/test/pseudo/unmaintained.ts +98 -0
- package/test/pseudo/unpopular.ts +98 -0
- package/test/pseudo/unstable.ts +98 -0
- package/test/pseudo/vuln.ts +625 -0
- package/test/pseudo/vulnerable.ts +137 -0
- package/test/pseudo/workspace.ts +111 -0
- package/test/pseudo.ts +558 -0
- package/tsconfig.json +3 -0
- package/tsconfig.publish.json +19 -0
- package/tsconfig.publish.tsbuildinfo +1 -0
- package/typedoc.mjs +2 -0
- package/dist/pseudo/vulnerable.d.ts +0 -8
- package/dist/pseudo/vulnerable.js +0 -17
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import t from 'tap'
|
|
2
|
+
import postcssSelectorParser from 'postcss-selector-parser'
|
|
3
|
+
import type { ParserState } from '../../src/types.ts'
|
|
4
|
+
import { overridden } from '../../src/pseudo/overridden.ts'
|
|
5
|
+
import {
|
|
6
|
+
getSimpleGraph,
|
|
7
|
+
newGraph,
|
|
8
|
+
newNode,
|
|
9
|
+
} from '../fixtures/graph.ts'
|
|
10
|
+
import { Spec } from '@vltpkg/spec/browser'
|
|
11
|
+
import type { GraphLike, NodeLike } from '@vltpkg/types'
|
|
12
|
+
import type { SpecOptions } from '@vltpkg/spec/browser'
|
|
13
|
+
|
|
14
|
+
const specOptions = {
|
|
15
|
+
registries: {
|
|
16
|
+
custom: 'http://example.com',
|
|
17
|
+
},
|
|
18
|
+
} satisfies SpecOptions
|
|
19
|
+
|
|
20
|
+
// Helper function to create an edge with overridden spec
|
|
21
|
+
const newOverriddenEdge = (
|
|
22
|
+
from: NodeLike,
|
|
23
|
+
specString: string,
|
|
24
|
+
to?: NodeLike,
|
|
25
|
+
) => {
|
|
26
|
+
const parts = specString.split('@')
|
|
27
|
+
const name = parts[0]!
|
|
28
|
+
const version = parts[1] || '^1.0.0'
|
|
29
|
+
const spec = Spec.parse(name, version, specOptions)
|
|
30
|
+
spec.overridden = true
|
|
31
|
+
const edge = {
|
|
32
|
+
name: spec.name,
|
|
33
|
+
from,
|
|
34
|
+
to,
|
|
35
|
+
spec,
|
|
36
|
+
type: 'prod' as const,
|
|
37
|
+
get optional() {
|
|
38
|
+
return false // prod type is never optional
|
|
39
|
+
},
|
|
40
|
+
get peer() {
|
|
41
|
+
return false // prod type is never peer
|
|
42
|
+
},
|
|
43
|
+
}
|
|
44
|
+
from.edgesOut.set(spec.name, edge)
|
|
45
|
+
if (to) {
|
|
46
|
+
to.edgesIn.add(edge)
|
|
47
|
+
}
|
|
48
|
+
from.graph.edges.add(edge)
|
|
49
|
+
return edge
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Helper function to create a regular edge (non-overridden)
|
|
53
|
+
const newRegularEdge = (
|
|
54
|
+
from: NodeLike,
|
|
55
|
+
specString: string,
|
|
56
|
+
to?: NodeLike,
|
|
57
|
+
) => {
|
|
58
|
+
const parts = specString.split('@')
|
|
59
|
+
const name = parts[0]!
|
|
60
|
+
const version = parts[1] || '^1.0.0'
|
|
61
|
+
const spec = Spec.parse(name, version, specOptions)
|
|
62
|
+
const edge = {
|
|
63
|
+
name: spec.name,
|
|
64
|
+
from,
|
|
65
|
+
to,
|
|
66
|
+
spec,
|
|
67
|
+
type: 'prod' as const,
|
|
68
|
+
get optional() {
|
|
69
|
+
return false // prod type is never optional
|
|
70
|
+
},
|
|
71
|
+
get peer() {
|
|
72
|
+
return false // prod type is never peer
|
|
73
|
+
},
|
|
74
|
+
}
|
|
75
|
+
from.edgesOut.set(spec.name, edge)
|
|
76
|
+
if (to) {
|
|
77
|
+
to.edgesIn.add(edge)
|
|
78
|
+
}
|
|
79
|
+
from.graph.edges.add(edge)
|
|
80
|
+
return edge
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// Create a graph with both overridden and non-overridden edges
|
|
84
|
+
export const getOverriddenGraph = (): GraphLike => {
|
|
85
|
+
const graph = newGraph('overridden-project')
|
|
86
|
+
const addNode = newNode(graph)
|
|
87
|
+
|
|
88
|
+
// Create nodes
|
|
89
|
+
const [a, b, c, d, e] = ['a', 'b', 'c', 'd', 'e'].map(i =>
|
|
90
|
+
addNode(i),
|
|
91
|
+
) as [NodeLike, NodeLike, NodeLike, NodeLike, NodeLike]
|
|
92
|
+
|
|
93
|
+
// Add nodes to graph
|
|
94
|
+
;[a, b, c, d, e].forEach(i => {
|
|
95
|
+
graph.nodes.set(i.id, i)
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
// Create overridden edges
|
|
99
|
+
newOverriddenEdge(graph.mainImporter, 'a@^1.0.0', a)
|
|
100
|
+
newOverriddenEdge(graph.mainImporter, 'b@^2.0.0', b)
|
|
101
|
+
newOverriddenEdge(a, 'c@^1.0.0', c)
|
|
102
|
+
|
|
103
|
+
// Create regular (non-overridden) edges
|
|
104
|
+
newRegularEdge(graph.mainImporter, 'd@^1.0.0', d)
|
|
105
|
+
newRegularEdge(graph.mainImporter, 'e@^1.0.0', e)
|
|
106
|
+
newRegularEdge(b, 'd@^1.0.0', d) // d is linked from both overridden and regular edges
|
|
107
|
+
|
|
108
|
+
// Create an overridden edge without a linked node (dangling edge)
|
|
109
|
+
newOverriddenEdge(graph.mainImporter, 'missing@^1.0.0')
|
|
110
|
+
|
|
111
|
+
return graph
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
t.test('selects edges with overridden specs', async t => {
|
|
115
|
+
const getState = (query: string, graph = getOverriddenGraph()) => {
|
|
116
|
+
const ast = postcssSelectorParser().astSync(query)
|
|
117
|
+
const current = ast.first.first
|
|
118
|
+
const state: ParserState = {
|
|
119
|
+
comment: '',
|
|
120
|
+
current,
|
|
121
|
+
initial: {
|
|
122
|
+
edges: new Set(graph.edges.values()),
|
|
123
|
+
nodes: new Set(graph.nodes.values()),
|
|
124
|
+
},
|
|
125
|
+
partial: {
|
|
126
|
+
edges: new Set(graph.edges.values()),
|
|
127
|
+
nodes: new Set(graph.nodes.values()),
|
|
128
|
+
},
|
|
129
|
+
collect: {
|
|
130
|
+
edges: new Set(),
|
|
131
|
+
nodes: new Set(),
|
|
132
|
+
},
|
|
133
|
+
cancellable: async () => {},
|
|
134
|
+
walk: async i => i,
|
|
135
|
+
retries: 0,
|
|
136
|
+
securityArchive: undefined,
|
|
137
|
+
importers: new Set(graph.importers),
|
|
138
|
+
signal: new AbortController().signal,
|
|
139
|
+
scopeIDs: [],
|
|
140
|
+
specificity: { idCounter: 0, commonCounter: 0 },
|
|
141
|
+
}
|
|
142
|
+
return state
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
await t.test(
|
|
146
|
+
'returns only overridden edges and their linked nodes',
|
|
147
|
+
async t => {
|
|
148
|
+
const res = await overridden(getState(':overridden'))
|
|
149
|
+
const edgeNames = [...res.partial.edges].map(e => e.name).sort()
|
|
150
|
+
const nodeNames = [...res.partial.nodes].map(n => n.name).sort()
|
|
151
|
+
|
|
152
|
+
t.strictSame(
|
|
153
|
+
edgeNames,
|
|
154
|
+
['a', 'b', 'c', 'missing'],
|
|
155
|
+
'should select only edges with overridden specs',
|
|
156
|
+
)
|
|
157
|
+
t.strictSame(
|
|
158
|
+
nodeNames,
|
|
159
|
+
['a', 'b', 'c'],
|
|
160
|
+
'should include only nodes that have incoming overridden edges',
|
|
161
|
+
)
|
|
162
|
+
t.matchSnapshot({
|
|
163
|
+
nodes: [...res.partial.nodes].map(n => n.name).sort(),
|
|
164
|
+
edges: [...res.partial.edges].map(e => e.name).sort(),
|
|
165
|
+
})
|
|
166
|
+
},
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
await t.test(
|
|
170
|
+
'removes nodes that no longer have incoming edges',
|
|
171
|
+
async t => {
|
|
172
|
+
const res = await overridden(getState(':overridden'))
|
|
173
|
+
const nodeNames = [...res.partial.nodes].map(n => n.name)
|
|
174
|
+
|
|
175
|
+
// Node 'd' and 'e' should be removed because they only have non-overridden edges
|
|
176
|
+
t.notOk(
|
|
177
|
+
nodeNames.includes('d'),
|
|
178
|
+
'node d should be removed as it has no overridden incoming edges',
|
|
179
|
+
)
|
|
180
|
+
t.notOk(
|
|
181
|
+
nodeNames.includes('e'),
|
|
182
|
+
'node e should be removed as it has no overridden incoming edges',
|
|
183
|
+
)
|
|
184
|
+
t.matchSnapshot({
|
|
185
|
+
nodes: [...res.partial.nodes].map(n => n.name).sort(),
|
|
186
|
+
edges: [...res.partial.edges].map(e => e.name).sort(),
|
|
187
|
+
})
|
|
188
|
+
},
|
|
189
|
+
)
|
|
190
|
+
|
|
191
|
+
await t.test(
|
|
192
|
+
'works with simple graph (no overridden edges)',
|
|
193
|
+
async t => {
|
|
194
|
+
// getSimpleGraph has no overridden edges, so result should be empty
|
|
195
|
+
const res = await overridden(
|
|
196
|
+
getState(':overridden', getSimpleGraph()),
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
t.strictSame(
|
|
200
|
+
[...res.partial.edges].map(e => e.name),
|
|
201
|
+
[],
|
|
202
|
+
'should return no edges when no edges are overridden',
|
|
203
|
+
)
|
|
204
|
+
t.strictSame(
|
|
205
|
+
[...res.partial.nodes].map(n => n.name),
|
|
206
|
+
[],
|
|
207
|
+
'should return no nodes when no edges are overridden',
|
|
208
|
+
)
|
|
209
|
+
t.matchSnapshot({
|
|
210
|
+
nodes: [...res.partial.nodes].map(n => n.name).sort(),
|
|
211
|
+
edges: [...res.partial.edges].map(e => e.name).sort(),
|
|
212
|
+
})
|
|
213
|
+
},
|
|
214
|
+
)
|
|
215
|
+
|
|
216
|
+
await t.test(
|
|
217
|
+
'handles edges with spec.overridden false',
|
|
218
|
+
async t => {
|
|
219
|
+
// Create a graph where specs explicitly have overridden = false
|
|
220
|
+
const graph = newGraph('explicit-false-project')
|
|
221
|
+
const addNode = newNode(graph)
|
|
222
|
+
const a = addNode('a')
|
|
223
|
+
graph.nodes.set(a.id, a)
|
|
224
|
+
|
|
225
|
+
const spec = Spec.parse('a', '^1.0.0', specOptions)
|
|
226
|
+
spec.overridden = false // explicitly set to false
|
|
227
|
+
|
|
228
|
+
const edge = {
|
|
229
|
+
name: spec.name,
|
|
230
|
+
from: graph.mainImporter,
|
|
231
|
+
to: a,
|
|
232
|
+
spec,
|
|
233
|
+
type: 'prod' as const,
|
|
234
|
+
get optional() {
|
|
235
|
+
return false // prod type is never optional
|
|
236
|
+
},
|
|
237
|
+
get peer() {
|
|
238
|
+
return false // prod type is never peer
|
|
239
|
+
},
|
|
240
|
+
}
|
|
241
|
+
graph.mainImporter.edgesOut.set(spec.name, edge)
|
|
242
|
+
a.edgesIn.add(edge)
|
|
243
|
+
graph.edges.add(edge)
|
|
244
|
+
|
|
245
|
+
const res = await overridden(getState(':overridden', graph))
|
|
246
|
+
|
|
247
|
+
t.strictSame(
|
|
248
|
+
[...res.partial.edges].map(e => e.name),
|
|
249
|
+
[],
|
|
250
|
+
'should not select edges with overridden explicitly set to false',
|
|
251
|
+
)
|
|
252
|
+
t.strictSame(
|
|
253
|
+
[...res.partial.nodes].map(n => n.name),
|
|
254
|
+
[],
|
|
255
|
+
'should not select nodes when overridden is explicitly false',
|
|
256
|
+
)
|
|
257
|
+
t.matchSnapshot({
|
|
258
|
+
nodes: [...res.partial.nodes].map(n => n.name).sort(),
|
|
259
|
+
edges: [...res.partial.edges].map(e => e.name).sort(),
|
|
260
|
+
})
|
|
261
|
+
},
|
|
262
|
+
)
|
|
263
|
+
|
|
264
|
+
await t.test('handles an empty partial state', async t => {
|
|
265
|
+
// Create a state with empty partial edges and nodes
|
|
266
|
+
const state = getState(':overridden')
|
|
267
|
+
state.partial.nodes.clear()
|
|
268
|
+
state.partial.edges.clear()
|
|
269
|
+
|
|
270
|
+
const res = await overridden(state)
|
|
271
|
+
t.strictSame(
|
|
272
|
+
[...res.partial.edges],
|
|
273
|
+
[],
|
|
274
|
+
'should return empty array of edges when starting with empty partial state',
|
|
275
|
+
)
|
|
276
|
+
t.strictSame(
|
|
277
|
+
[...res.partial.nodes],
|
|
278
|
+
[],
|
|
279
|
+
'should return empty array of nodes when starting with empty partial state',
|
|
280
|
+
)
|
|
281
|
+
t.matchSnapshot({
|
|
282
|
+
nodes: [...res.partial.nodes].map(n => n.name),
|
|
283
|
+
edges: [...res.partial.edges].map(e => e.name),
|
|
284
|
+
})
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
await t.test(
|
|
288
|
+
'preserves edges with both overridden and non-overridden pointing to same node',
|
|
289
|
+
async t => {
|
|
290
|
+
// Node 'd' in our test graph has both overridden and non-overridden edges pointing to it
|
|
291
|
+
// But since we filter out non-overridden edges, 'd' should only appear if it has overridden edges
|
|
292
|
+
const res = await overridden(getState(':overridden'))
|
|
293
|
+
const nodeNames = [...res.partial.nodes].map(n => n.name)
|
|
294
|
+
|
|
295
|
+
// In our graph, 'd' has incoming edges from both overridden (b->d) and non-overridden (root->d)
|
|
296
|
+
// But since we remove non-overridden edges, 'd' should only be included if it has overridden edges
|
|
297
|
+
// Since 'b' has an overridden edge to 'd', 'd' should be included
|
|
298
|
+
t.ok(
|
|
299
|
+
nodeNames.includes('a'),
|
|
300
|
+
'node a should be included (has overridden edge from root)',
|
|
301
|
+
)
|
|
302
|
+
t.ok(
|
|
303
|
+
nodeNames.includes('b'),
|
|
304
|
+
'node b should be included (has overridden edge from root)',
|
|
305
|
+
)
|
|
306
|
+
t.ok(
|
|
307
|
+
nodeNames.includes('c'),
|
|
308
|
+
'node c should be included (has overridden edge from a)',
|
|
309
|
+
)
|
|
310
|
+
|
|
311
|
+
t.matchSnapshot({
|
|
312
|
+
nodes: [...res.partial.nodes].map(n => n.name).sort(),
|
|
313
|
+
edges: [...res.partial.edges].map(e => e.name).sort(),
|
|
314
|
+
})
|
|
315
|
+
},
|
|
316
|
+
)
|
|
317
|
+
})
|