Skip to content

Commit 89710c8

Browse files
committed
Add directive location is correct validation
1 parent b553a76 commit 89710c8

File tree

2 files changed

+272
-69
lines changed

2 files changed

+272
-69
lines changed

src/type/__tests__/validation-test.js

Lines changed: 182 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {
2020
GraphQLString,
2121
} from '../../';
2222
import { parse } from '../../language/parser';
23+
import { Source } from '../../language/source';
2324
import { validateSchema } from '../validate';
2425
import { buildSchema } from '../../utilities/buildASTSchema';
2526
import { extendSchema } from '../../utilities/extendSchema';
@@ -725,6 +726,10 @@ describe('Type System: Input Objects must have fields', () => {
725726
'Input Object type SomeInputObject must define one or more fields.',
726727
locations: [{ line: 6, column: 7 }, { line: 4, column: 9 }],
727728
},
729+
{
730+
message: 'Directive @test not allowed at INPUT_OBJECT location.',
731+
locations: [{ line: 4, column: 38 }, { line: 2, column: 9 }],
732+
},
728733
]);
729734
});
730735

@@ -1836,16 +1841,16 @@ describe('Type System: Schema directives must validate', () => {
18361841
}
18371842
18381843
type Query @testA @testB {
1839-
test: AnInterface @testB
1844+
test: AnInterface @testC
18401845
}
18411846
1842-
directive @testA on SCHEMA | OBJECT | INTERFACE | UNION | SCALAR | INPUT_OBJECT
1843-
directive @testB on SCHEMA | OBJECT | INTERFACE | UNION | SCALAR | INPUT_OBJECT
1847+
directive @testA on SCHEMA | OBJECT | INTERFACE | UNION | SCALAR | INPUT_OBJECT | ENUM
1848+
directive @testB on SCHEMA | OBJECT | INTERFACE | UNION | SCALAR | INPUT_OBJECT | ENUM
18441849
directive @testC on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
18451850
directive @testD on FIELD_DEFINITION | ARGUMENT_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION
18461851
18471852
interface AnInterface @testA {
1848-
field: String! @testB
1853+
field: String! @testC
18491854
}
18501855
18511856
type TypeA implements AnInterface @testA {
@@ -1889,109 +1894,225 @@ describe('Type System: Schema directives must validate', () => {
18891894
]);
18901895
});
18911896

1892-
it('rejects a Schema with same schema directive used twice', () => {
1897+
it('rejects a Schema with same directive used twice per location', () => {
18931898
const schema = buildSchema(`
1894-
schema @testA @testA {
1899+
directive @schema on SCHEMA
1900+
directive @object on OBJECT
1901+
directive @interface on INTERFACE
1902+
directive @union on UNION
1903+
directive @scalar on SCALAR
1904+
directive @input_object on INPUT_OBJECT
1905+
directive @enum on ENUM
1906+
directive @field_definition on FIELD_DEFINITION
1907+
directive @enum_value on ENUM_VALUE
1908+
directive @input_field_definition on INPUT_FIELD_DEFINITION
1909+
directive @argument_definition on ARGUMENT_DEFINITION
1910+
1911+
schema @schema @schema {
18951912
query: Query
18961913
}
1897-
type Query {
1898-
test: String
1899-
}
19001914
1901-
directive @testA on SCHEMA
1902-
`);
1903-
expect(validateSchema(schema)).to.deep.equal([
1904-
{
1905-
message: 'Directive @testA used twice at the same location.',
1906-
locations: [{ line: 2, column: 14 }, { line: 2, column: 21 }],
1907-
},
1908-
]);
1909-
});
1910-
1911-
it('rejects a Schema with same definition directive used twice', () => {
1912-
const schema = buildSchema(`
1913-
directive @testA on OBJECT | INTERFACE | UNION | SCALAR | INPUT_OBJECT
1914-
1915-
type Query implements SomeInterface @testA @testA {
1916-
test: String
1915+
type Query implements SomeInterface @object @object {
1916+
test(arg: SomeInput @argument_definition @argument_definition): String
19171917
}
19181918
1919-
interface SomeInterface @testA @testA {
1920-
test: String
1919+
interface SomeInterface @interface @interface {
1920+
test: String @field_definition @field_definition
19211921
}
19221922
1923-
union SomeUnion @testA @testA = Query
1923+
union SomeUnion @union @union = Query
19241924
1925-
scalar SomeScalar @testA @testA
1925+
scalar SomeScalar @scalar @scalar
19261926
1927-
enum SomeEnum @testA @testA {
1928-
SOME_VALUE
1927+
enum SomeEnum @enum @enum {
1928+
SOME_VALUE @enum_value @enum_value
19291929
}
19301930
1931-
input SomeInput @testA @testA {
1932-
some_input_field: String
1931+
input SomeInput @input_object @input_object {
1932+
some_input_field: String @input_field_definition @input_field_definition
19331933
}
19341934
`);
19351935
expect(validateSchema(schema)).to.deep.equal([
19361936
{
1937-
message: 'Directive @testA used twice at the same location.',
1938-
locations: [{ line: 4, column: 43 }, { line: 4, column: 50 }],
1937+
message: 'Directive @schema used twice at the same location.',
1938+
locations: [{ line: 14, column: 14 }, { line: 14, column: 22 }],
19391939
},
19401940
{
1941-
message: 'Directive @testA used twice at the same location.',
1942-
locations: [{ line: 8, column: 31 }, { line: 8, column: 38 }],
1941+
message:
1942+
'Directive @argument_definition used twice at the same location.',
1943+
locations: [{ line: 19, column: 29 }, { line: 19, column: 50 }],
19431944
},
19441945
{
1945-
message: 'Directive @testA used twice at the same location.',
1946-
locations: [{ line: 12, column: 23 }, { line: 12, column: 30 }],
1946+
message: 'Directive @object used twice at the same location.',
1947+
locations: [{ line: 18, column: 43 }, { line: 18, column: 51 }],
19471948
},
19481949
{
1949-
message: 'Directive @testA used twice at the same location.',
1950-
locations: [{ line: 14, column: 25 }, { line: 14, column: 32 }],
1950+
message: 'Directive @field_definition used twice at the same location.',
1951+
locations: [{ line: 23, column: 22 }, { line: 23, column: 40 }],
19511952
},
19521953
{
1953-
message: 'Directive @testA used twice at the same location.',
1954-
locations: [{ line: 16, column: 21 }, { line: 16, column: 28 }],
1954+
message: 'Directive @interface used twice at the same location.',
1955+
locations: [{ line: 22, column: 31 }, { line: 22, column: 42 }],
1956+
},
1957+
{
1958+
message:
1959+
'Directive @input_field_definition not allowed at FIELD_DEFINITION location.',
1960+
locations: [{ line: 35, column: 34 }, { line: 11, column: 7 }],
1961+
},
1962+
{
1963+
message:
1964+
'Directive @input_field_definition not allowed at FIELD_DEFINITION location.',
1965+
locations: [{ line: 35, column: 58 }, { line: 11, column: 7 }],
1966+
},
1967+
{
1968+
message:
1969+
'Directive @input_field_definition used twice at the same location.',
1970+
locations: [{ line: 35, column: 34 }, { line: 35, column: 58 }],
1971+
},
1972+
{
1973+
message: 'Directive @input_object used twice at the same location.',
1974+
locations: [{ line: 34, column: 23 }, { line: 34, column: 37 }],
1975+
},
1976+
{
1977+
message: 'Directive @union used twice at the same location.',
1978+
locations: [{ line: 26, column: 23 }, { line: 26, column: 30 }],
1979+
},
1980+
{
1981+
message: 'Directive @scalar used twice at the same location.',
1982+
locations: [{ line: 28, column: 25 }, { line: 28, column: 33 }],
1983+
},
1984+
{
1985+
message: 'Directive @enum_value used twice at the same location.',
1986+
locations: [{ line: 31, column: 20 }, { line: 31, column: 32 }],
19551987
},
1988+
{
1989+
message: 'Directive @enum used twice at the same location.',
1990+
locations: [{ line: 30, column: 21 }, { line: 30, column: 27 }],
1991+
},
1992+
]);
1993+
});
1994+
1995+
it('rejects a Schema with directive used again in extension', () => {
1996+
const schema = buildSchema(
1997+
new Source(`
1998+
directive @testA on OBJECT
1999+
2000+
type Query @testA {
2001+
test: String
2002+
}
2003+
`),
2004+
'schema.graphql',
2005+
);
2006+
const extensions = parse(
2007+
new Source(
2008+
`
2009+
extend type Query @testA
2010+
`,
2011+
'extensions.graphql',
2012+
),
2013+
);
2014+
const extendedSchema = extendSchema(schema, extensions);
2015+
expect(validateSchema(extendedSchema)).to.deep.equal([
19562016
{
19572017
message: 'Directive @testA used twice at the same location.',
1958-
locations: [{ line: 20, column: 23 }, { line: 20, column: 30 }],
2018+
locations: [{ line: 4, column: 20 }, { line: 2, column: 29 }],
19592019
},
19602020
]);
19612021
});
19622022

1963-
it('rejects a Schema with same field and arg directive used twice', () => {
2023+
it('rejects a Schema with directives used in wrong location', () => {
19642024
const schema = buildSchema(`
1965-
directive @testA on FIELD_DEFINITION | ENUM_VALUE | INPUT_FIELD_DEFINITION | ARGUMENT_DEFINITION
2025+
directive @schema on SCHEMA
2026+
directive @object on OBJECT
2027+
directive @interface on INTERFACE
2028+
directive @union on UNION
2029+
directive @scalar on SCALAR
2030+
directive @input_object on INPUT_OBJECT
2031+
directive @enum on ENUM
2032+
directive @field_definition on FIELD_DEFINITION
2033+
directive @enum_value on ENUM_VALUE
2034+
directive @input_field_definition on INPUT_FIELD_DEFINITION
2035+
directive @argument_definition on ARGUMENT_DEFINITION
2036+
2037+
schema @object {
2038+
query: Query
2039+
}
19662040
1967-
type Query implements SomeInterface {
1968-
test(arg: String @testA @testA): String @testA @testA
2041+
type Query implements SomeInterface @schema {
2042+
test(arg: SomeInput @field_definition): String
19692043
}
19702044
1971-
interface SomeInterface {
1972-
test: String @testA @testA
2045+
interface SomeInterface @interface {
2046+
test: String @argument_definition
2047+
}
2048+
2049+
union SomeUnion @interface = Query
2050+
2051+
scalar SomeScalar @enum_value
2052+
2053+
enum SomeEnum @input_object {
2054+
SOME_VALUE @enum
19732055
}
19742056
1975-
input SomeInput {
1976-
some_input_field: String @testA @testA
2057+
input SomeInput @object {
2058+
some_input_field: String @union
19772059
}
19782060
`);
1979-
expect(validateSchema(schema)).to.deep.equal([
2061+
const extensions = parse(
2062+
new Source(
2063+
`
2064+
extend type Query @testA
2065+
`,
2066+
'extensions.graphql',
2067+
),
2068+
);
2069+
const extendedSchema = extendSchema(schema, extensions);
2070+
expect(validateSchema(extendedSchema)).to.deep.equal([
19802071
{
1981-
message: 'Directive @testA used twice at the same location.',
1982-
locations: [{ line: 5, column: 26 }, { line: 5, column: 33 }],
2072+
message: 'Directive @object not allowed at SCHEMA location.',
2073+
locations: [{ line: 14, column: 14 }, { line: 3, column: 7 }],
19832074
},
19842075
{
1985-
message: 'Directive @testA used twice at the same location.',
1986-
locations: [{ line: 5, column: 49 }, { line: 5, column: 56 }],
2076+
message:
2077+
'Directive @field_definition not allowed at ARGUMENT_DEFINITION location.',
2078+
locations: [{ line: 19, column: 29 }, { line: 9, column: 7 }],
19872079
},
19882080
{
1989-
message: 'Directive @testA used twice at the same location.',
1990-
locations: [{ line: 9, column: 22 }, { line: 9, column: 29 }],
2081+
message: 'Directive @schema not allowed at OBJECT location.',
2082+
locations: [{ line: 18, column: 43 }, { line: 2, column: 7 }],
19912083
},
19922084
{
1993-
message: 'Directive @testA used twice at the same location.',
1994-
locations: [{ line: 13, column: 34 }, { line: 13, column: 41 }],
2085+
message: 'No directive @testA defined.',
2086+
locations: [{ line: 2, column: 29 }],
2087+
},
2088+
{
2089+
message:
2090+
'Directive @argument_definition not allowed at FIELD_DEFINITION location.',
2091+
locations: [{ line: 23, column: 22 }, { line: 12, column: 7 }],
2092+
},
2093+
{
2094+
message: 'Directive @union not allowed at FIELD_DEFINITION location.',
2095+
locations: [{ line: 35, column: 34 }, { line: 5, column: 7 }],
2096+
},
2097+
{
2098+
message: 'Directive @object not allowed at INPUT_OBJECT location.',
2099+
locations: [{ line: 34, column: 23 }, { line: 3, column: 7 }],
2100+
},
2101+
{
2102+
message: 'Directive @interface not allowed at UNION location.',
2103+
locations: [{ line: 26, column: 23 }, { line: 4, column: 7 }],
2104+
},
2105+
{
2106+
message: 'Directive @enum_value not allowed at SCALAR location.',
2107+
locations: [{ line: 28, column: 25 }, { line: 10, column: 7 }],
2108+
},
2109+
{
2110+
message: 'Directive @enum not allowed at ENUM_VALUE location.',
2111+
locations: [{ line: 31, column: 20 }, { line: 8, column: 7 }],
2112+
},
2113+
{
2114+
message: 'Directive @input_object not allowed at ENUM location.',
2115+
locations: [{ line: 30, column: 21 }, { line: 7, column: 7 }],
19952116
},
19962117
]);
19972118
});

0 commit comments

Comments
 (0)