From f4dee2803c22f7e5fde913b9743cc6de345bb871 Mon Sep 17 00:00:00 2001 From: Ivan Goncharov Date: Thu, 30 Aug 2018 01:41:27 +0300 Subject: [PATCH] Allow to add optional args to fields implemented from interfaces (#1493) I reviewed all `isNonNullType` calls and it the last one that needs to be fixed to complete #1274 --- src/type/__tests__/validation-test.js | 17 +++++++++++------ src/type/validate.js | 12 ++++++------ 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/type/__tests__/validation-test.js b/src/type/__tests__/validation-test.js index 8a1947dd46..2713a45b0b 100644 --- a/src/type/__tests__/validation-test.js +++ b/src/type/__tests__/validation-test.js @@ -1703,20 +1703,25 @@ describe('Objects must adhere to Interface they implement', () => { } interface AnotherInterface { - field(input: String): String + field(baseArg: String): String } type AnotherObject implements AnotherInterface { - field(input: String, anotherInput: String!): String + field( + baseArg: String, + requiredArg: String! + optionalArg1: String, + optionalArg2: String = "", + ): String } `); expect(validateSchema(schema)).to.deep.equal([ { message: - 'Object field argument AnotherObject.field(anotherInput:) is of ' + - 'required type String! but is not also provided by the Interface ' + - 'field AnotherInterface.field.', - locations: [{ line: 11, column: 44 }, { line: 7, column: 9 }], + 'Object field AnotherObject.field includes required argument ' + + 'requiredArg that is missing from the Interface field ' + + 'AnotherInterface.field.', + locations: [{ line: 13, column: 11 }, { line: 7, column: 9 }], }, ]); }); diff --git a/src/type/validate.js b/src/type/validate.js index 1d8bdb13a1..22f3423d58 100644 --- a/src/type/validate.js +++ b/src/type/validate.js @@ -13,10 +13,10 @@ import { isUnionType, isEnumType, isInputObjectType, - isNonNullType, isNamedType, isInputType, isOutputType, + isRequiredArgument, } from './definition'; import type { GraphQLObjectType, @@ -438,13 +438,13 @@ function validateObjectImplementsInterface( for (const objectArg of objectField.args) { const argName = objectArg.name; const ifaceArg = find(ifaceField.args, arg => arg.name === argName); - if (!ifaceArg && isNonNullType(objectArg.type)) { + if (!ifaceArg && isRequiredArgument(objectArg)) { context.reportError( - `Object field argument ${object.name}.${fieldName}(${argName}:) ` + - `is of required type ${inspect(objectArg.type)} but is not also ` + - `provided by the Interface field ${iface.name}.${fieldName}.`, + `Object field ${object.name}.${fieldName} includes required ` + + `argument ${argName} that is missing from the Interface field ` + + `${iface.name}.${fieldName}.`, [ - getFieldArgTypeNode(object, fieldName, argName), + getFieldArgNode(object, fieldName, argName), getFieldNode(iface, fieldName), ], );