|
1 | 1 | import { describe, it } from 'mocha'; |
2 | 2 |
|
| 3 | +import { expectJSON } from '../../__testUtils__/expectJSON'; |
| 4 | + |
3 | 5 | import { parse } from '../../language/parser'; |
4 | 6 |
|
5 | 7 | import type { GraphQLSchema } from '../../type/schema'; |
6 | 8 |
|
7 | 9 | import { extendSchema } from '../../utilities/extendSchema'; |
8 | 10 |
|
9 | 11 | import { UniqueDirectivesPerLocationRule } from '../rules/UniqueDirectivesPerLocationRule'; |
| 12 | +import { validateSDL } from '../validate'; |
10 | 13 |
|
11 | 14 | import { |
12 | 15 | expectSDLValidationErrors, |
@@ -42,6 +45,14 @@ function expectSDLErrors(sdlStr: string, schema?: GraphQLSchema) { |
42 | 45 | ); |
43 | 46 | } |
44 | 47 |
|
| 48 | +function expectExperimentalSDLErrors(sdlStr: string, schema?: GraphQLSchema) { |
| 49 | + const doc = parse(sdlStr, { |
| 50 | + experimentalDirectivesOnDirectiveDefinitions: true, |
| 51 | + }); |
| 52 | + const errors = validateSDL(doc, schema, [UniqueDirectivesPerLocationRule]); |
| 53 | + return expectJSON(errors); |
| 54 | +} |
| 55 | + |
45 | 56 | describe('Validate: Directives Are Unique Per Location', () => { |
46 | 57 | it('no directives', () => { |
47 | 58 | expectValid(` |
@@ -391,4 +402,74 @@ describe('Validate: Directives Are Unique Per Location', () => { |
391 | 402 | }, |
392 | 403 | ]); |
393 | 404 | }); |
| 405 | + |
| 406 | + it('duplicate directives on directive definitions', () => { |
| 407 | + expectExperimentalSDLErrors(` |
| 408 | + directive @nonRepeatable on DIRECTIVE_DEFINITION |
| 409 | +
|
| 410 | + directive @testDirective @nonRepeatable @nonRepeatable on FIELD_DEFINITION |
| 411 | + `).toDeepEqual([ |
| 412 | + { |
| 413 | + message: |
| 414 | + 'The directive "@nonRepeatable" can only be used once at this location.', |
| 415 | + locations: [ |
| 416 | + { line: 4, column: 32 }, |
| 417 | + { line: 4, column: 47 }, |
| 418 | + ], |
| 419 | + }, |
| 420 | + ]); |
| 421 | + }); |
| 422 | + |
| 423 | + it('duplicate directives on directive extensions', () => { |
| 424 | + expectExperimentalSDLErrors(` |
| 425 | + directive @nonRepeatable on DIRECTIVE_DEFINITION |
| 426 | +
|
| 427 | + extend directive @testDirective @nonRepeatable @nonRepeatable |
| 428 | + `).toDeepEqual([ |
| 429 | + { |
| 430 | + message: |
| 431 | + 'The directive "@nonRepeatable" can only be used once at this location.', |
| 432 | + locations: [ |
| 433 | + { line: 4, column: 39 }, |
| 434 | + { line: 4, column: 54 }, |
| 435 | + ], |
| 436 | + }, |
| 437 | + ]); |
| 438 | + }); |
| 439 | + |
| 440 | + it('duplicate directives between directive definitions and extensions', () => { |
| 441 | + expectExperimentalSDLErrors(` |
| 442 | + directive @nonRepeatable on DIRECTIVE_DEFINITION |
| 443 | +
|
| 444 | + directive @testDirective @nonRepeatable on FIELD_DEFINITION |
| 445 | + extend directive @testDirective @nonRepeatable |
| 446 | + `).toDeepEqual([ |
| 447 | + { |
| 448 | + message: |
| 449 | + 'The directive "@nonRepeatable" can only be used once at this location.', |
| 450 | + locations: [ |
| 451 | + { line: 4, column: 32 }, |
| 452 | + { line: 5, column: 39 }, |
| 453 | + ], |
| 454 | + }, |
| 455 | + ]); |
| 456 | + }); |
| 457 | + |
| 458 | + it('duplicate directives between directive extensions', () => { |
| 459 | + expectExperimentalSDLErrors(` |
| 460 | + directive @nonRepeatable on DIRECTIVE_DEFINITION |
| 461 | +
|
| 462 | + extend directive @testDirective @nonRepeatable |
| 463 | + extend directive @testDirective @nonRepeatable |
| 464 | + `).toDeepEqual([ |
| 465 | + { |
| 466 | + message: |
| 467 | + 'The directive "@nonRepeatable" can only be used once at this location.', |
| 468 | + locations: [ |
| 469 | + { line: 4, column: 39 }, |
| 470 | + { line: 5, column: 39 }, |
| 471 | + ], |
| 472 | + }, |
| 473 | + ]); |
| 474 | + }); |
394 | 475 | }); |
0 commit comments