Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f570db3

Browse files
authored
fix(gatsby): Fix invalid algorithm of fragment cycles detection (gatsbyjs#21128)
1 parent d8dfcc1 commit f570db3

File tree

2 files changed

+133
-4
lines changed

2 files changed

+133
-4
lines changed

packages/gatsby/src/query/__tests__/query-compiler.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,132 @@ describe(`actual compiling`, () => {
276276
expect(result.get(`mockFile`)).toMatchSnapshot()
277277
})
278278

279+
it(`handles multiple fragment usages`, async () => {
280+
const nodes = [
281+
createGatsbyDoc(
282+
`mockFile1`,
283+
`query mockFileQuery1 {
284+
allDirectory {
285+
nodes {
286+
...Foo
287+
...Bar
288+
}
289+
}
290+
}`
291+
),
292+
createGatsbyDoc(
293+
`mockFile2`,
294+
`query mockFileQuery2 {
295+
allDirectory {
296+
nodes {
297+
...Bar
298+
}
299+
}
300+
}`
301+
),
302+
createGatsbyDoc(
303+
`mockComponent1`,
304+
`fragment Bar on Directory {
305+
parent {
306+
...Foo
307+
}
308+
}
309+
fragment Foo on Directory {
310+
id
311+
}
312+
`
313+
),
314+
]
315+
316+
const errors = []
317+
const result = processQueries({
318+
schema,
319+
parsedQueries: nodes,
320+
addError: e => {
321+
errors.push(e)
322+
},
323+
})
324+
expect(errors.length).toEqual(0)
325+
expect(result.get(`mockFile1`)).toMatchInlineSnapshot(`
326+
Object {
327+
"hash": "hash",
328+
"isHook": false,
329+
"isStaticQuery": false,
330+
"name": "mockFileQuery1",
331+
"originalText": "query mockFileQuery1 {
332+
allDirectory {
333+
nodes {
334+
...Foo
335+
...Bar
336+
}
337+
}
338+
}",
339+
"path": "mockFile1",
340+
"text": "fragment Foo on Directory {
341+
id
342+
}
343+
344+
fragment Bar on Directory {
345+
id
346+
parent {
347+
__typename
348+
id
349+
...Foo
350+
}
351+
}
352+
353+
query mockFileQuery1 {
354+
allDirectory {
355+
nodes {
356+
id
357+
...Foo
358+
...Bar
359+
}
360+
}
361+
}
362+
",
363+
}
364+
`)
365+
expect(result.get(`mockFile2`)).toMatchInlineSnapshot(`
366+
Object {
367+
"hash": "hash",
368+
"isHook": false,
369+
"isStaticQuery": false,
370+
"name": "mockFileQuery2",
371+
"originalText": "query mockFileQuery2 {
372+
allDirectory {
373+
nodes {
374+
...Bar
375+
}
376+
}
377+
}",
378+
"path": "mockFile2",
379+
"text": "fragment Bar on Directory {
380+
id
381+
parent {
382+
__typename
383+
id
384+
...Foo
385+
}
386+
}
387+
388+
fragment Foo on Directory {
389+
id
390+
}
391+
392+
query mockFileQuery2 {
393+
allDirectory {
394+
nodes {
395+
id
396+
...Bar
397+
}
398+
}
399+
}
400+
",
401+
}
402+
`)
403+
})
404+
279405
it(`handles circular fragments`, async () => {
280406
const nodes = [
281407
createGatsbyDoc(

packages/gatsby/src/query/query-compiler.js

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,7 @@ const determineUsedFragmentsForDefinition = (
431431
definition,
432432
definitionsByName,
433433
fragmentsUsedByFragment,
434-
visitedFragments = new Set()
434+
traversalPath = []
435435
) => {
436436
const { def, name, isFragment, filePath } = definition
437437
const cachedUsedFragments = fragmentsUsedByFragment.get(name)
@@ -445,10 +445,12 @@ const determineUsedFragmentsForDefinition = (
445445
const name = node.name.value
446446
const fragmentDefinition = definitionsByName.get(name)
447447
if (fragmentDefinition) {
448-
if (visitedFragments.has(name)) {
448+
if (traversalPath.includes(name)) {
449+
// Already visited this fragment during current traversal.
450+
// Visiting it again will cause a stack overflow
449451
return
450452
}
451-
visitedFragments.add(name)
453+
traversalPath.push(name)
452454
usedFragments.add(name)
453455
const {
454456
usedFragments: usedFragmentsForFragment,
@@ -457,8 +459,9 @@ const determineUsedFragmentsForDefinition = (
457459
fragmentDefinition,
458460
definitionsByName,
459461
fragmentsUsedByFragment,
460-
visitedFragments
462+
traversalPath
461463
)
464+
traversalPath.pop()
462465
usedFragmentsForFragment.forEach(fragmentName =>
463466
usedFragments.add(fragmentName)
464467
)

0 commit comments

Comments
 (0)