-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Reviewed By: lynnshaoyu Differential Revision: D69484406 fbshipit-source-id: 9bf41b6908ec80f8d6daf0c1bd12dc952ac56734
- Loading branch information
1 parent
134aea4
commit aeaac5f
Showing
3 changed files
with
107 additions
and
1 deletion.
There are no files selected for viewing
54 changes: 54 additions & 0 deletions
54
compiler/crates/relay-transforms/tests/validate_unused_variables/fixtures/cycle-bug.expected
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
==================================== INPUT ==================================== | ||
# expected-to-throw | ||
|
||
fragment FragmentC on User { | ||
url(relative: true, site: $varX) | ||
nearest_neighbor { | ||
...FragmentD | ||
} | ||
} | ||
|
||
fragment FragmentD on User { | ||
url(relative: true, site: $varY) | ||
...FragmentC | ||
} | ||
|
||
query QueryA($varX: String, $varY: String) { | ||
me { | ||
# By visiting FragmentC first, we incorrectly end up recording that | ||
# FragmentD has only reads its own variable ($varY) and omit that it | ||
# transitively reads $varX via its spread of FragmentC | ||
|
||
# When we traverse into FragmentC we initialize the cache for FragmentC with | ||
# an empty set of variables. We then traverse into FragmentD which | ||
# initializes the cache with an empty set of variables for FragmentD. | ||
# | ||
# FragmentD then records its own read of $varY, and attempts to traverse | ||
# into FragmentC. Here we hit the empty initialized cache for FragmentC. As | ||
# a result we _incorrectly_ treat the used variables for FragmentD as just: | ||
# $varY. | ||
# | ||
# We now pop back up to FragmentC which correctly records its read variables | ||
# as $varX and $varY, and the dependencies for QueryA are correctly validated. | ||
# | ||
# BUT! We've left behind an invalid cache record for FragmentD. | ||
...FragmentC | ||
} | ||
} | ||
|
||
query QueryB($varX: String, $varY: String) { | ||
me { | ||
# Now as we traverse into FragmentD we get a cache hit (the invalid one left | ||
# behind by our traversal of QueryA) and incorrectly conclude FragmentD only | ||
# read $varY, and _incorrectly_ report $varX as unused by QueryB. | ||
...FragmentD | ||
} | ||
} | ||
==================================== ERROR ==================================== | ||
✖︎ Variable `$varX` is never used in operation `QueryB` | ||
|
||
cycle-bug.graphql:38:14 | ||
37 │ | ||
38 │ query QueryB($varX: String, $varY: String) { | ||
│ ^^^^^ | ||
39 │ me { |
45 changes: 45 additions & 0 deletions
45
compiler/crates/relay-transforms/tests/validate_unused_variables/fixtures/cycle-bug.graphql
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
# expected-to-throw | ||
|
||
fragment FragmentC on User { | ||
url(relative: true, site: $varX) | ||
nearest_neighbor { | ||
...FragmentD | ||
} | ||
} | ||
|
||
fragment FragmentD on User { | ||
url(relative: true, site: $varY) | ||
...FragmentC | ||
} | ||
|
||
query QueryA($varX: String, $varY: String) { | ||
me { | ||
# By visiting FragmentC first, we incorrectly end up recording that | ||
# FragmentD has only reads its own variable ($varY) and omit that it | ||
# transitively reads $varX via its spread of FragmentC | ||
|
||
# When we traverse into FragmentC we initialize the cache for FragmentC with | ||
# an empty set of variables. We then traverse into FragmentD which | ||
# initializes the cache with an empty set of variables for FragmentD. | ||
# | ||
# FragmentD then records its own read of $varY, and attempts to traverse | ||
# into FragmentC. Here we hit the empty initialized cache for FragmentC. As | ||
# a result we _incorrectly_ treat the used variables for FragmentD as just: | ||
# $varY. | ||
# | ||
# We now pop back up to FragmentC which correctly records its read variables | ||
# as $varX and $varY, and the dependencies for QueryA are correctly validated. | ||
# | ||
# BUT! We've left behind an invalid cache record for FragmentD. | ||
...FragmentC | ||
} | ||
} | ||
|
||
query QueryB($varX: String, $varY: String) { | ||
me { | ||
# Now as we traverse into FragmentD we get a cache hit (the invalid one left | ||
# behind by our traversal of QueryA) and incorrectly conclude FragmentD only | ||
# read $varY, and _incorrectly_ report $varX as unused by QueryB. | ||
...FragmentD | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters