From 502cb54abdcf74eaa5e2741465f766fdfa764570 Mon Sep 17 00:00:00 2001 From: spawnia Date: Wed, 16 May 2018 20:24:13 +0200 Subject: [PATCH 1/2] Add tests to validate Input Objects do not contain non-nullable circular references The first two to tests are there to avoid false positives when checking for circular references. Tests 3 and 4 are failing right now but show what should happen. https://github.com/facebook/graphql/pull/445 contains the proposed additions to the spec. --- src/language/__tests__/schema-parser-test.js | 48 ++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/src/language/__tests__/schema-parser-test.js b/src/language/__tests__/schema-parser-test.js index 1ad0acd05e..c0965d7c60 100644 --- a/src/language/__tests__/schema-parser-test.js +++ b/src/language/__tests__/schema-parser-test.js @@ -802,6 +802,54 @@ input Hello { ); }); + it('Allow simple input object with nullable circular reference', () => { + expect(() => + parse(` + input Hello { + world: String + self: Hello + }`), + ).to.not.throw(); + }); + + it('Allow input object with circular reference broken up by a list', () => { + expect(() => + parse(` + input Hello { + world: String + self: [Hello!]! + }`), + ).to.not.throw(); + }); + + it('Reject simple input object with non-nullable circular reference', () => { + expectSyntaxError( + ` + input Hello { + self: Hello! + string: String + }`, + 'input: Hello contains non-nullable circular reference through field: self', + { line: 3, column: 8 }, + ); + }); + + it('Reject input object with non-nullable circular reference spread across multiple inputs', () => { + expectSyntaxError( + ` + input Hello { + world: World! + string: String + } + input World { + hello: Hello! + string: String + }`, + 'input: Hello contains non-nullable circular reference through field: world', + { line: 3, column: 8 }, + ); + }); + it('Directive with incorrect locations', () => { expectSyntaxError( ` From ce6765ffd61b5ca65037ad4208f1d1f5d7c58cad Mon Sep 17 00:00:00 2001 From: spawnia Date: Thu, 17 May 2018 22:51:13 +0200 Subject: [PATCH 2/2] Move tests for unbroken circular references to validation into seperate file Todo: Actually implement the validation rule, possibly add some more tests --- src/language/__tests__/schema-parser-test.js | 48 ----------- .../InputObjectCircularReferences-test.js | 80 +++++++++++++++++++ 2 files changed, 80 insertions(+), 48 deletions(-) create mode 100644 src/validation/__tests__/InputObjectCircularReferences-test.js diff --git a/src/language/__tests__/schema-parser-test.js b/src/language/__tests__/schema-parser-test.js index c0965d7c60..1ad0acd05e 100644 --- a/src/language/__tests__/schema-parser-test.js +++ b/src/language/__tests__/schema-parser-test.js @@ -802,54 +802,6 @@ input Hello { ); }); - it('Allow simple input object with nullable circular reference', () => { - expect(() => - parse(` - input Hello { - world: String - self: Hello - }`), - ).to.not.throw(); - }); - - it('Allow input object with circular reference broken up by a list', () => { - expect(() => - parse(` - input Hello { - world: String - self: [Hello!]! - }`), - ).to.not.throw(); - }); - - it('Reject simple input object with non-nullable circular reference', () => { - expectSyntaxError( - ` - input Hello { - self: Hello! - string: String - }`, - 'input: Hello contains non-nullable circular reference through field: self', - { line: 3, column: 8 }, - ); - }); - - it('Reject input object with non-nullable circular reference spread across multiple inputs', () => { - expectSyntaxError( - ` - input Hello { - world: World! - string: String - } - input World { - hello: Hello! - string: String - }`, - 'input: Hello contains non-nullable circular reference through field: world', - { line: 3, column: 8 }, - ); - }); - it('Directive with incorrect locations', () => { expectSyntaxError( ` diff --git a/src/validation/__tests__/InputObjectCircularReferences-test.js b/src/validation/__tests__/InputObjectCircularReferences-test.js new file mode 100644 index 0000000000..10f3afb564 --- /dev/null +++ b/src/validation/__tests__/InputObjectCircularReferences-test.js @@ -0,0 +1,80 @@ +/** + * Copyright (c) 2015-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +import { describe, it } from 'mocha'; +import { expectPassesRule, expectFailsRule } from './harness'; +import { + InputObjectCircularReferences, + unbrokenCircularReferenceMessage, +} from '../rules/InputObjectCircularReferences'; + +function unbrokenCircularReference(defName, fieldName, line, column) { + return { + message: unbrokenCircularReferenceMessage(defName, fieldName), + locations: [{ line, column }], + }; +} + +describe('Validate: Executable definitions', () => { + it('Allow simple input object with nullable circular reference', () => { + expectPassesRule( + InputObjectCircularReferences, + ` + input Example { + self: Example + value: String + } + `, + ); + }); + + it('Allow input object with circular reference broken up by a list', () => { + expectPassesRule( + InputObjectCircularReferences, + ` + input Example { + self: [Example!]! + value: String + } + `, + ); + }); + + it('Reject simple input object with non-nullable circular reference', () => { + expectFailsRule( + InputObjectCircularReferences, + ` + input Example { + value: String + self: Example! + } + `, + [unbrokenCircularReference('Example', 'self', 3, 8)], + ); + }); + + it('Reject input object with non-nullable circular reference spread across multiple inputs', () => { + expectFailsRule( + InputObjectCircularReferences, + ` + input First { + second: Second! + value: String + } + + input Second { + first: First! + value: String + } + `, + [ + unbrokenCircularReference('First', 'second', 3, 8), + unbrokenCircularReference('Second', 'first', 8, 8), + ], + ); + }); +});