Skip to content

Commit

Permalink
Add oneOf directive
Browse files Browse the repository at this point in the history
This adds the @OneOf directive as a default directive to indicate
Objects and Input Objects as OneOf Objects/Input Objects which ensure
there is exactly one non-null entry. Future commits will work to
implement this directive.
  • Loading branch information
erikkessler1 committed Mar 18, 2022
1 parent da57238 commit 99189d9
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 4 deletions.
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ export {
GraphQLSkipDirective,
GraphQLDeprecatedDirective,
GraphQLSpecifiedByDirective,
GraphQLOneOfDirective,
// "Enum" of Type Kinds
TypeKind,
// Constant Deprecation Reason
Expand Down
6 changes: 6 additions & 0 deletions src/type/__tests__/introspection-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -989,6 +989,12 @@ describe('Introspection', () => {
},
],
},
{
name: 'oneOf',
isRepeatable: false,
locations: ['OBJECT', 'INPUT_OBJECT'],
args: [],
},
],
},
},
Expand Down
12 changes: 12 additions & 0 deletions src/type/directives.ts
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,17 @@ export const GraphQLSpecifiedByDirective: GraphQLDirective =
},
});

/**
* Used to declare an Input Object as a OneOf Input Objects and an Object as a OneOf Object.
*/
export const GraphQLOneOfDirective: GraphQLDirective = new GraphQLDirective({
name: 'oneOf',
description:
'Indicates an Object is a OneOf Object or an Input Object is a OneOf Input Object.',
locations: [DirectiveLocation.OBJECT, DirectiveLocation.INPUT_OBJECT],
args: {},
});

/**
* The full list of specified directives.
*/
Expand All @@ -218,6 +229,7 @@ export const specifiedDirectives: ReadonlyArray<GraphQLDirective> =
GraphQLSkipDirective,
GraphQLDeprecatedDirective,
GraphQLSpecifiedByDirective,
GraphQLOneOfDirective,
]);

export function isSpecifiedDirective(directive: GraphQLDirective): boolean {
Expand Down
1 change: 1 addition & 0 deletions src/type/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export {
GraphQLSkipDirective,
GraphQLDeprecatedDirective,
GraphQLSpecifiedByDirective,
GraphQLOneOfDirective,
// Constant Deprecation Reason
DEFAULT_DEPRECATION_REASON,
} from './directives';
Expand Down
13 changes: 9 additions & 4 deletions src/utilities/__tests__/buildASTSchema-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import {
assertDirective,
GraphQLDeprecatedDirective,
GraphQLIncludeDirective,
GraphQLOneOfDirective,
GraphQLSkipDirective,
GraphQLSpecifiedByDirective,
} from '../../type/directives';
Expand Down Expand Up @@ -222,7 +223,7 @@ describe('Schema Builder', () => {
it('Maintains @include, @skip & @specifiedBy', () => {
const schema = buildSchema('type Query');

expect(schema.getDirectives()).to.have.lengthOf(4);
expect(schema.getDirectives()).to.have.lengthOf(5);
expect(schema.getDirective('skip')).to.equal(GraphQLSkipDirective);
expect(schema.getDirective('include')).to.equal(GraphQLIncludeDirective);
expect(schema.getDirective('deprecated')).to.equal(
Expand All @@ -231,6 +232,7 @@ describe('Schema Builder', () => {
expect(schema.getDirective('specifiedBy')).to.equal(
GraphQLSpecifiedByDirective,
);
expect(schema.getDirective('oneOf')).to.equal(GraphQLOneOfDirective);
});

it('Overriding directives excludes specified', () => {
Expand All @@ -239,9 +241,10 @@ describe('Schema Builder', () => {
directive @include on FIELD
directive @deprecated on FIELD_DEFINITION
directive @specifiedBy on FIELD_DEFINITION
directive @oneOf on OBJECT
`);

expect(schema.getDirectives()).to.have.lengthOf(4);
expect(schema.getDirectives()).to.have.lengthOf(5);
expect(schema.getDirective('skip')).to.not.equal(GraphQLSkipDirective);
expect(schema.getDirective('include')).to.not.equal(
GraphQLIncludeDirective,
Expand All @@ -252,18 +255,20 @@ describe('Schema Builder', () => {
expect(schema.getDirective('specifiedBy')).to.not.equal(
GraphQLSpecifiedByDirective,
);
expect(schema.getDirective('oneOf')).to.not.equal(GraphQLOneOfDirective);
});

it('Adding directives maintains @include, @skip & @specifiedBy', () => {
it('Adding directives maintains @include, @skip, @deprecated, @specifiedBy, and @oneOf', () => {
const schema = buildSchema(`
directive @foo(arg: Int) on FIELD
`);

expect(schema.getDirectives()).to.have.lengthOf(5);
expect(schema.getDirectives()).to.have.lengthOf(6);
expect(schema.getDirective('skip')).to.not.equal(undefined);
expect(schema.getDirective('include')).to.not.equal(undefined);
expect(schema.getDirective('deprecated')).to.not.equal(undefined);
expect(schema.getDirective('specifiedBy')).to.not.equal(undefined);
expect(schema.getDirective('oneOf')).to.not.equal(undefined);
});

it('Type modifiers', () => {
Expand Down
2 changes: 2 additions & 0 deletions src/utilities/__tests__/findBreakingChanges-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { describe, it } from 'mocha';
import {
GraphQLDeprecatedDirective,
GraphQLIncludeDirective,
GraphQLOneOfDirective,
GraphQLSkipDirective,
GraphQLSpecifiedByDirective,
} from '../../type/directives';
Expand Down Expand Up @@ -802,6 +803,7 @@ describe('findBreakingChanges', () => {
GraphQLSkipDirective,
GraphQLIncludeDirective,
GraphQLSpecifiedByDirective,
GraphQLOneOfDirective,
],
});

Expand Down
5 changes: 5 additions & 0 deletions src/utilities/__tests__/printSchema-test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -656,6 +656,11 @@ describe('Type System Printer', () => {
url: String!
) on SCALAR
"""
Indicates an Object is a OneOf Object or an Input Object is a OneOf Input Object.
"""
directive @oneOf on OBJECT | INPUT_OBJECT
"""
A GraphQL Schema defines the capabilities of a GraphQL server. It exposes all available types and directives on the server, as well as the entry points for query, mutation, and subscription operations.
"""
Expand Down

0 comments on commit 99189d9

Please sign in to comment.