123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334 |
- local parse = require 'graphql.parse'
- local validate = require 'graphql.validate'
- local schema = require 'tests/data/schema'
- local function expectError(message, document)
- if not message then
- expect(function() validate(schema, parse(document)) end).to_not.fail()
- else
- expect(function() validate(schema, parse(document)) end).to.fail.with(message)
- end
- end
- describe('rules', function()
- local document
- describe('uniqueOperationNames', function()
- local message = 'Multiple operations exist named'
- it('errors if two operations have the same name', function()
- expectError(message, [[
- query foo { }
- query foo { }
- ]])
- end)
- it('passes if all operations have different names', function()
- expectError(nil, [[
- query foo { }
- query bar { }
- ]])
- end)
- end)
- describe('loneAnonymousOperation', function()
- local message = 'Cannot have more than one operation when'
- it('fails if there is more than one operation and one of them is anonymous', function()
- expectError(message, [[
- query { }
- query named { }
- ]])
- expectError(message, [[
- query named { }
- query { }
- ]])
- expectError(message, [[
- query { }
- query { }
- ]])
- end)
- it('passes if there is one anonymous operation', function()
- expectError(nil, '{}')
- end)
- it('passes if there are two named operations', function()
- expectError(nil, [[
- query one {}
- query two {}
- ]])
- end)
- end)
- describe('fieldsDefinedOnType', function()
- local message = 'is not defined on type'
- it('fails if a field does not exist on an object type', function()
- expectError(message, '{ doggy { name } }')
- expectError(message, '{ dog { age } }')
- end)
- it('passes if all fields exist on object types', function()
- expectError(nil, '{ dog { name } }')
- end)
- it('understands aliases', function()
- expectError(nil, '{ doggy: dog { name } }')
- expectError(message, '{ dog: doggy { name } }')
- end)
- end)
- describe('argumentsDefinedOnType', function()
- local message = 'Non%-existent argument'
- it('passes if no arguments are supplied', function()
- expectError(nil, '{ dog { isHouseTrained } }')
- end)
- it('errors if an argument name does not match the schema', function()
- expectError(message, [[{
- dog {
- doesKnowCommand(doggyCommand: SIT)
- }
- }]])
- end)
- it('errors if an argument is supplied to a field that takes none', function()
- expectError(message, [[{
- dog {
- name(truncateToLength: 32)
- }
- }]])
- end)
- it('passes if all argument names match the schema', function()
- expectError(nil, [[{
- dog {
- doesKnowCommand(dogCommand: SIT)
- }
- }]])
- end)
- end)
- describe('scalarFieldsAreLeaves', function()
- local message = 'Scalar values cannot have subselections'
- it('fails if a scalar field has a subselection', function()
- expectError(message, '{ dog { name { firstLetter } } }')
- end)
- it('passes if all scalar fields are leaves', function()
- expectError(nil, '{ dog { name nickname } }')
- end)
- end)
- describe('compositeFieldsAreNotLeaves', function()
- local message = 'Composite types must have subselections'
-
- it('fails if an object is a leaf', function()
- expectError(message, '{ dog }')
- end)
- it('fails if an interface is a leaf', function()
- expectError(message, '{ pet }')
- end)
- it('fails if a union is a leaf', function()
- expectError(message, '{ catOrDog }')
- end)
- it('passes if all composite types have subselections', function()
- expectError(nil, '{ dog { name } pet { } }')
- end)
- end)
- describe('unambiguousSelections', function()
- it('fails if two fields with identical response keys have different types', function()
- expectError('Type name mismatch', [[{
- dog {
- barkVolume
- barkVolume: name
- }
- }]])
- end)
- it('fails if two fields have different argument sets', function()
- expectError('Argument mismatch', [[{
- dog {
- doesKnowCommand(dogCommand: SIT)
- doesKnowCommand(dogCommand: DOWN)
- }
- }]])
- end)
- it('passes if fields are identical', function()
- expectError(nil, [[{
- dog {
- doesKnowCommand(dogCommand: SIT)
- doesKnowCommand: doesKnowCommand(dogCommand: SIT)
- }
- }]])
- end)
- end)
- describe('uniqueArgumentNames', function()
- local message = 'Encountered multiple arguments named'
- it('fails if a field has two arguments with the same name', function()
- expectError(message, [[{
- dog {
- doesKnowCommand(dogCommand: SIT, dogCommand: DOWN)
- }
- }]])
- end)
- end)
- describe('argumentsOfCorrectType', function()
- it('fails if an argument has an incorrect type', function()
- expectError('Expected enum value', [[{
- dog {
- doesKnowCommand(dogCommand: 4)
- }
- }]])
- end)
- end)
- describe('requiredArgumentsPresent', function()
- local message = 'was not supplied'
- it('fails if a non-null argument is not present', function()
- expectError(message, [[{
- dog {
- doesKnowCommand
- }
- }]])
- end)
- end)
- describe('uniqueFragmentNames', function()
- local message = 'Encountered multiple fragments named'
- it('fails if there are two fragment definitions with the same name', function()
- expectError(message, [[
- query { dog { ...nameFragment } }
- fragment nameFragment on Dog { name }
- fragment nameFragment on Dog { name }
- ]])
- end)
- it('passes if all fragment definitions have different names', function()
- expectError(nil, [[
- query { dog { ...one ...two } }
- fragment one on Dog { name }
- fragment two on Dog { name }
- ]])
- end)
- end)
- describe('fragmentHasValidType', function()
- it('fails if a framgent refers to a non-composite type', function()
- expectError('Fragment type must be an Object, Interface, or Union', 'fragment f on DogCommand {}')
- end)
- it('fails if a fragment refers to a non-existent type', function()
- expectError('Fragment refers to non%-existent type', 'fragment f on Hyena {}')
- end)
- it('passes if a fragment refers to a composite type', function()
- expectError(nil, '{ dog { ...f } } fragment f on Dog {}')
- end)
- end)
- describe('noUnusedFragments', function()
- local message = 'was not used'
- it('fails if a fragment is not used', function()
- expectError(message, 'fragment f on Dog {}')
- end)
- end)
- describe('fragmentSpreadTargetDefined', function()
- local message = 'Fragment spread refers to non%-existent'
- it('fails if the fragment does not exist', function()
- expectError(message, '{ dog { ...f } }')
- end)
- end)
- describe('fragmentDefinitionHasNoCycles', function()
- local message = 'Fragment definition has cycles'
- it('fails if a fragment spread has cycles', function()
- expectError(message, [[
- { dog { ...f } }
- fragment f on Dog { ...g }
- fragment g on Dog { ...h }
- fragment h on Dog { ...f }
- ]])
- end)
- end)
- describe('fragmentSpreadIsPossible', function()
- local message = 'Fragment type condition is not possible'
- it('fails if a fragment type condition refers to a different object than the parent object', function()
- expectError(message, [[
- { dog { ...f } }
- fragment f on Cat { }
- ]])
- end)
- it('fails if a fragment type condition refers to an interface that the parent object does not implement', function()
- expectError(message, [[
- { dog { ...f } }
- fragment f on Sentient { }
- ]])
- end)
- it('fails if a fragment type condition refers to a union that the parent object does not belong to', function()
- expectError(message, [[
- { dog { ...f } }
- fragment f on HumanOrAlien { }
- ]])
- end)
- end)
- describe('uniqueInputObjectFields', function()
- local message = 'Multiple input object fields named'
- it('fails if an input object has two fields with the same name', function()
- expectError(message, [[
- {
- dog {
- complicatedField(complicatedArgument: {x: "hi", x: "hi"})
- }
- }
- ]])
- end)
- it('passes if an input object has nested fields with the same name', function()
- expectError(nil, [[
- {
- dog {
- complicatedField(complicatedArgument: {x: "hi", z: {x: "hi"}})
- }
- }
- ]])
- end)
- end)
- describe('directivesAreDefined', function()
- local message = 'Unknown directive'
- it('fails if a directive does not exist', function()
- expectError(message, 'query @someRandomDirective {}')
- end)
- it('passes if directives exists', function()
- expectError(nil, 'query @skip {}')
- end)
- end)
- end)
|