-
Notifications
You must be signed in to change notification settings - Fork 221
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
UniqueFragmentNames and UniqueOperationNames rules. closes #40
- Loading branch information
1 parent
cf23a34
commit f568967
Showing
5 changed files
with
252 additions
and
0 deletions.
There are no files selected for viewing
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
28 changes: 28 additions & 0 deletions
28
src/main/scala/sangria/validation/rules/UniqueFragmentNames.scala
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,28 @@ | ||
package sangria.validation.rules | ||
|
||
import sangria.ast | ||
import sangria.ast.AstVisitorCommand._ | ||
import sangria.validation._ | ||
|
||
import scala.collection.mutable.{Set => MutableSet} | ||
|
||
/** | ||
* Unique fragment names | ||
* | ||
* A GraphQL document is only valid if all defined fragments have unique names. | ||
*/ | ||
class UniqueFragmentNames extends ValidationRule { | ||
override def visitor(ctx: ValidationContext) = new AstValidatingVisitor { | ||
val knownFragmentNames = MutableSet[String]() | ||
|
||
override val onEnter: ValidationVisit = { | ||
case fragDef: ast.FragmentDefinition => | ||
if (knownFragmentNames contains fragDef.name) | ||
Left(Vector(DuplicateFragmentNameViolation(fragDef.name, ctx.sourceMapper, fragDef.position.toList))) | ||
else { | ||
knownFragmentNames += fragDef.name | ||
Right(Continue) | ||
} | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/main/scala/sangria/validation/rules/UniqueOperationNames.scala
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,28 @@ | ||
package sangria.validation.rules | ||
|
||
import sangria.ast | ||
import sangria.ast.AstVisitorCommand._ | ||
import sangria.validation._ | ||
|
||
import scala.collection.mutable.{Set => MutableSet} | ||
|
||
/** | ||
* Unique operation names | ||
* | ||
* A GraphQL document is only valid if all defined operations have unique names. | ||
*/ | ||
class UniqueOperationNames extends ValidationRule { | ||
override def visitor(ctx: ValidationContext) = new AstValidatingVisitor { | ||
val knownOpNames = MutableSet[String]() | ||
|
||
override val onEnter: ValidationVisit = { | ||
case ast.OperationDefinition(_, Some(name), _, _, _, pos) => | ||
if (knownOpNames contains name) | ||
Left(Vector(DuplicateOperationNameViolation(name, ctx.sourceMapper, pos.toList))) | ||
else { | ||
knownOpNames += name | ||
Right(Continue) | ||
} | ||
} | ||
} | ||
} |
98 changes: 98 additions & 0 deletions
98
src/test/scala/sangria/validation/rules/UniqueFragmentNamesSpec.scala
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,98 @@ | ||
package sangria.validation.rules | ||
|
||
import org.scalatest.WordSpec | ||
import sangria.util.{Pos, ValidationSupport} | ||
|
||
class UniqueFragmentNamesSpec extends WordSpec with ValidationSupport { | ||
|
||
override val defaultRule = Some(new UniqueFragmentNames) | ||
|
||
"Validate: Unique fragment names" should { | ||
"no fragments" in expectPasses( | ||
""" | ||
{ | ||
field | ||
} | ||
""") | ||
|
||
"one fragment" in expectPasses( | ||
""" | ||
{ | ||
...fragA | ||
} | ||
fragment fragA on Type { | ||
field | ||
} | ||
""") | ||
|
||
"many fragments" in expectPasses( | ||
""" | ||
{ | ||
...fragA | ||
...fragB | ||
...fragC | ||
} | ||
fragment fragA on Type { | ||
fieldA | ||
} | ||
fragment fragB on Type { | ||
fieldB | ||
} | ||
fragment fragC on Type { | ||
fieldC | ||
} | ||
""") | ||
|
||
"inline fragments are always unique" in expectPasses( | ||
""" | ||
{ | ||
...on Type { | ||
fieldA | ||
} | ||
...on Type { | ||
fieldB | ||
} | ||
} | ||
""") | ||
|
||
"fragment and operation named the same" in expectPasses( | ||
""" | ||
query Foo { | ||
...Foo | ||
} | ||
fragment Foo on Type { | ||
field | ||
} | ||
""") | ||
|
||
"fragments named the same" in expectFails( | ||
""" | ||
{ | ||
...fragA | ||
} | ||
fragment fragA on Type { | ||
fieldA | ||
} | ||
fragment fragA on Type { | ||
fieldB | ||
} | ||
""", | ||
List( | ||
"There can only be one fragment named 'fragA'." -> Some(Pos(8, 9)) | ||
)) | ||
|
||
"fragments named the same without being referenced" in expectFails( | ||
""" | ||
fragment fragA on Type { | ||
fieldA | ||
} | ||
fragment fragA on Type { | ||
fieldB | ||
} | ||
""", | ||
List( | ||
"There can only be one fragment named 'fragA'." -> Some(Pos(5, 9)) | ||
)) | ||
} | ||
} |
90 changes: 90 additions & 0 deletions
90
src/test/scala/sangria/validation/rules/UniqueOperationNamesSpec.scala
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,90 @@ | ||
package sangria.validation.rules | ||
|
||
import org.scalatest.WordSpec | ||
import sangria.util.{Pos, ValidationSupport} | ||
|
||
class UniqueOperationNamesSpec extends WordSpec with ValidationSupport { | ||
|
||
override val defaultRule = Some(new UniqueOperationNames) | ||
|
||
"Validate: Unique operation names" should { | ||
"no operations" in expectPasses( | ||
""" | ||
fragment fragA on Type { | ||
field | ||
} | ||
""") | ||
|
||
"one anon operation" in expectPasses( | ||
""" | ||
{ | ||
field | ||
} | ||
""") | ||
|
||
"one named operation" in expectPasses( | ||
""" | ||
query Foo { | ||
field | ||
} | ||
""") | ||
|
||
"multiple operations" in expectPasses( | ||
""" | ||
query Foo { | ||
field | ||
} | ||
query Bar { | ||
field | ||
} | ||
""") | ||
|
||
"multiple operations of different types" in expectPasses( | ||
""" | ||
query Foo { | ||
field | ||
} | ||
mutation Bar { | ||
field | ||
} | ||
""") | ||
|
||
"fragment and operation named the same" in expectPasses( | ||
""" | ||
query Foo { | ||
...Foo | ||
} | ||
fragment Foo on Type { | ||
field | ||
} | ||
""") | ||
|
||
"multiple operations of same name" in expectFails( | ||
""" | ||
query Foo { | ||
fieldA | ||
} | ||
query Foo { | ||
fieldB | ||
} | ||
""", | ||
List( | ||
"There can only be one operation named 'Foo'." -> Some(Pos(5, 9)) | ||
)) | ||
|
||
"multiple operations of same name of different types" in expectFails( | ||
""" | ||
query Foo { | ||
fieldA | ||
} | ||
mutation Foo { | ||
fieldB | ||
} | ||
""", | ||
List( | ||
"There can only be one operation named 'Foo'." -> Some(Pos(5, 9)) | ||
)) | ||
} | ||
} |