mirror of
https://github.com/retailcrm/graphql-php.git
synced 2024-11-21 20:36:05 +03:00
Fix CS in tests/Validator
This commit is contained in:
parent
ec54d6152b
commit
caa50d6db9
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,13 +11,14 @@ use GraphQL\Validator\Rules\DisableIntrospection;
|
||||
class DisableIntrospectionTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Disable Introspection
|
||||
|
||||
/**
|
||||
* @see it('fails if the query contains __schema')
|
||||
*/
|
||||
public function testQueryContainsSchema() : void
|
||||
{
|
||||
$this->expectFailsRule(new DisableIntrospection(DisableIntrospection::ENABLED), '
|
||||
$this->expectFailsRule(
|
||||
new DisableIntrospection(DisableIntrospection::ENABLED),
|
||||
'
|
||||
query {
|
||||
__schema {
|
||||
queryType {
|
||||
@ -23,16 +27,26 @@ class DisableIntrospectionTest extends ValidatorTestCase
|
||||
}
|
||||
}
|
||||
',
|
||||
[$this->error(3, 9)]
|
||||
[$this->error(3, 9)]
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
private function error($line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
DisableIntrospection::introspectionDisabledMessage(),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('fails if the query contains __type')
|
||||
*/
|
||||
public function testQueryContainsType() : void
|
||||
{
|
||||
$this->expectFailsRule(new DisableIntrospection(DisableIntrospection::ENABLED), '
|
||||
$this->expectFailsRule(
|
||||
new DisableIntrospection(DisableIntrospection::ENABLED),
|
||||
'
|
||||
query {
|
||||
__type(
|
||||
name: "Query"
|
||||
@ -50,7 +64,9 @@ class DisableIntrospectionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testValidQuery() : void
|
||||
{
|
||||
$this->expectPassesRule(new DisableIntrospection(DisableIntrospection::ENABLED), '
|
||||
$this->expectPassesRule(
|
||||
new DisableIntrospection(DisableIntrospection::ENABLED),
|
||||
'
|
||||
query {
|
||||
user {
|
||||
name
|
||||
@ -60,7 +76,8 @@ class DisableIntrospectionTest extends ValidatorTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,7 +85,9 @@ class DisableIntrospectionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testQueryWhenDisabled() : void
|
||||
{
|
||||
$this->expectPassesRule(new DisableIntrospection(DisableIntrospection::DISABLED), '
|
||||
$this->expectPassesRule(
|
||||
new DisableIntrospection(DisableIntrospection::DISABLED),
|
||||
'
|
||||
query {
|
||||
__type(
|
||||
name: "Query"
|
||||
@ -76,7 +95,8 @@ class DisableIntrospectionTest extends ValidatorTestCase
|
||||
name
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,7 +106,9 @@ class DisableIntrospectionTest extends ValidatorTestCase
|
||||
{
|
||||
$disableIntrospection = new DisableIntrospection(DisableIntrospection::DISABLED);
|
||||
$disableIntrospection->setEnabled(DisableIntrospection::ENABLED);
|
||||
$this->expectFailsRule($disableIntrospection, '
|
||||
$this->expectFailsRule(
|
||||
$disableIntrospection,
|
||||
'
|
||||
query {
|
||||
__type(
|
||||
name: "Query"
|
||||
@ -106,7 +128,9 @@ class DisableIntrospectionTest extends ValidatorTestCase
|
||||
{
|
||||
$disableIntrospection = new DisableIntrospection(DisableIntrospection::ENABLED);
|
||||
$disableIntrospection->setEnabled(DisableIntrospection::DISABLED);
|
||||
$this->expectPassesRule($disableIntrospection, '
|
||||
$this->expectPassesRule(
|
||||
$disableIntrospection,
|
||||
'
|
||||
query {
|
||||
__type(
|
||||
name: "Query"
|
||||
@ -114,15 +138,7 @@ class DisableIntrospectionTest extends ValidatorTestCase
|
||||
name
|
||||
}
|
||||
}
|
||||
');
|
||||
}
|
||||
|
||||
|
||||
private function error($line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
DisableIntrospection::introspectionDisabledMessage(),
|
||||
[ new SourceLocation($line, $column) ]
|
||||
'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,27 +1,31 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
use GraphQL\Language\SourceLocation;
|
||||
use GraphQL\Validator\Rules\ExecutableDefinitions;
|
||||
use GraphQL\Validator\Rules\KnownDirectives;
|
||||
|
||||
class ExecutableDefinitionsTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Executable definitions
|
||||
|
||||
/**
|
||||
* @see it('with only operation')
|
||||
*/
|
||||
public function testWithOnlyOperation() : void
|
||||
{
|
||||
$this->expectPassesRule(new ExecutableDefinitions, '
|
||||
$this->expectPassesRule(
|
||||
new ExecutableDefinitions(),
|
||||
'
|
||||
query Foo {
|
||||
dog {
|
||||
name
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -29,7 +33,9 @@ class ExecutableDefinitionsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testWithOperationAndFragment() : void
|
||||
{
|
||||
$this->expectPassesRule(new ExecutableDefinitions, '
|
||||
$this->expectPassesRule(
|
||||
new ExecutableDefinitions(),
|
||||
'
|
||||
query Foo {
|
||||
dog {
|
||||
name
|
||||
@ -40,7 +46,8 @@ class ExecutableDefinitionsTest extends ValidatorTestCase
|
||||
fragment Frag on Dog {
|
||||
name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,7 +55,9 @@ class ExecutableDefinitionsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testWithTypeDefinition() : void
|
||||
{
|
||||
$this->expectFailsRule(new ExecutableDefinitions, '
|
||||
$this->expectFailsRule(
|
||||
new ExecutableDefinitions(),
|
||||
'
|
||||
query Foo {
|
||||
dog {
|
||||
name
|
||||
@ -66,14 +75,15 @@ class ExecutableDefinitionsTest extends ValidatorTestCase
|
||||
[
|
||||
$this->nonExecutableDefinition('Cow', 8, 12),
|
||||
$this->nonExecutableDefinition('Dog', 12, 19),
|
||||
]);
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function nonExecutableDefinition($defName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
ExecutableDefinitions::nonExecutableDefinitionMessage($defName),
|
||||
[ new SourceLocation($line, $column) ]
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,18 +11,20 @@ use GraphQL\Validator\Rules\FieldsOnCorrectType;
|
||||
class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Fields on correct type
|
||||
|
||||
/**
|
||||
* @see it('Object field selection')
|
||||
*/
|
||||
public function testObjectFieldSelection() : void
|
||||
{
|
||||
$this->expectPassesRule(new FieldsOnCorrectType(), '
|
||||
$this->expectPassesRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment objectFieldSelection on Dog {
|
||||
__typename
|
||||
name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -27,12 +32,15 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAliasedObjectFieldSelection() : void
|
||||
{
|
||||
$this->expectPassesRule(new FieldsOnCorrectType, '
|
||||
$this->expectPassesRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment aliasedObjectFieldSelection on Dog {
|
||||
tn : __typename
|
||||
otherName : name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -40,12 +48,15 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInterfaceFieldSelection() : void
|
||||
{
|
||||
$this->expectPassesRule(new FieldsOnCorrectType, '
|
||||
$this->expectPassesRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment interfaceFieldSelection on Pet {
|
||||
__typename
|
||||
name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,11 +64,14 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAliasedInterfaceFieldSelection() : void
|
||||
{
|
||||
$this->expectPassesRule(new FieldsOnCorrectType, '
|
||||
$this->expectPassesRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment interfaceFieldSelection on Pet {
|
||||
otherName : name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,11 +79,14 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testLyingAliasSelection() : void
|
||||
{
|
||||
$this->expectPassesRule(new FieldsOnCorrectType, '
|
||||
$this->expectPassesRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment lyingAliasSelection on Dog {
|
||||
name : nickname
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -77,11 +94,14 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testIgnoresFieldsOnUnknownType() : void
|
||||
{
|
||||
$this->expectPassesRule(new FieldsOnCorrectType, '
|
||||
$this->expectPassesRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment unknownSelection on UnknownType {
|
||||
unknownField
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -89,7 +109,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testReportsErrorsWhenTypeIsKnownAgain() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment typeKnownAgain on Pet {
|
||||
unknown_pet_field {
|
||||
... on Cat {
|
||||
@ -99,17 +121,27 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
}',
|
||||
[
|
||||
$this->undefinedField('unknown_pet_field', 'Pet', [], [], 3, 9),
|
||||
$this->undefinedField('unknown_cat_field', 'Cat', [], [], 5, 13)
|
||||
$this->undefinedField('unknown_cat_field', 'Cat', [], [], 5, 13),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function undefinedField($field, $type, $suggestedTypes, $suggestedFields, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
FieldsOnCorrectType::undefinedFieldMessage($field, $type, $suggestedTypes, $suggestedFields),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('Field not defined on fragment')
|
||||
*/
|
||||
public function testFieldNotDefinedOnFragment() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment fieldNotDefined on Dog {
|
||||
meowVolume
|
||||
}',
|
||||
@ -122,7 +154,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testIgnoresDeeplyUnknownField() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment deepFieldNotDefined on Dog {
|
||||
unknown_field {
|
||||
deeper_unknown_field
|
||||
@ -137,7 +171,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSubFieldNotDefined() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment subFieldNotDefined on Human {
|
||||
pets {
|
||||
unknown_field
|
||||
@ -152,7 +188,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testFieldNotDefinedOnInlineFragment() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment fieldNotDefined on Pet {
|
||||
... on Dog {
|
||||
meowVolume
|
||||
@ -167,7 +205,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAliasedFieldTargetNotDefined() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment aliasedFieldTargetNotDefined on Dog {
|
||||
volume : mooVolume
|
||||
}',
|
||||
@ -180,7 +220,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAliasedLyingFieldTargetNotDefined() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment aliasedLyingFieldTargetNotDefined on Dog {
|
||||
barkVolume : kawVolume
|
||||
}',
|
||||
@ -193,7 +235,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNotDefinedOnInterface() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment notDefinedOnInterface on Pet {
|
||||
tailLength
|
||||
}',
|
||||
@ -206,7 +250,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDefinedOnImplmentorsButNotOnInterface() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment definedOnImplementorsButNotInterface on Pet {
|
||||
nickname
|
||||
}',
|
||||
@ -219,7 +265,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMetaFieldSelectionOnUnion() : void
|
||||
{
|
||||
$this->expectPassesRule(new FieldsOnCorrectType, '
|
||||
$this->expectPassesRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment directFieldSelectionOnUnion on CatOrDog {
|
||||
__typename
|
||||
}'
|
||||
@ -231,7 +279,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDirectFieldSelectionOnUnion() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment directFieldSelectionOnUnion on CatOrDog {
|
||||
directField
|
||||
}',
|
||||
@ -244,7 +294,9 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDefinedOnImplementorsQueriedOnUnion() : void
|
||||
{
|
||||
$this->expectFailsRule(new FieldsOnCorrectType, '
|
||||
$this->expectFailsRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment definedOnImplementorsQueriedOnUnion on CatOrDog {
|
||||
name
|
||||
}',
|
||||
@ -255,32 +307,39 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
[],
|
||||
3,
|
||||
9
|
||||
)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Describe: Fields on correct type error message
|
||||
|
||||
/**
|
||||
* @see it('valid field in inline fragment')
|
||||
*/
|
||||
public function testValidFieldInInlineFragment() : void
|
||||
{
|
||||
$this->expectPassesRule(new FieldsOnCorrectType, '
|
||||
$this->expectPassesRule(
|
||||
new FieldsOnCorrectType(),
|
||||
'
|
||||
fragment objectFieldSelection on Pet {
|
||||
... on Dog {
|
||||
name
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
// Describe: Fields on correct type error message
|
||||
|
||||
/**
|
||||
* @see it('Works with no suggestions')
|
||||
*/
|
||||
public function testWorksWithNoSuggestions() : void
|
||||
{
|
||||
$this->assertEquals('Cannot query field "f" on type "T".', FieldsOnCorrectType::undefinedFieldMessage('f', 'T', [], []));
|
||||
$this->assertEquals(
|
||||
'Cannot query field "f" on type "T".',
|
||||
FieldsOnCorrectType::undefinedFieldMessage('f', 'T', [], [])
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -324,12 +383,15 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
$expected = 'Cannot query field "f" on type "T". ' .
|
||||
'Did you mean to use an inline fragment on "A", "B", "C", "D", or "E"?';
|
||||
|
||||
$this->assertEquals($expected, FieldsOnCorrectType::undefinedFieldMessage(
|
||||
'f',
|
||||
'T',
|
||||
['A', 'B', 'C', 'D', 'E', 'F'],
|
||||
[]
|
||||
));
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
FieldsOnCorrectType::undefinedFieldMessage(
|
||||
'f',
|
||||
'T',
|
||||
['A', 'B', 'C', 'D', 'E', 'F'],
|
||||
[]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -340,19 +402,14 @@ class FieldsOnCorrectTypeTest extends ValidatorTestCase
|
||||
$expected = 'Cannot query field "f" on type "T". ' .
|
||||
'Did you mean "z", "y", "x", "w", or "v"?';
|
||||
|
||||
$this->assertEquals($expected, FieldsOnCorrectType::undefinedFieldMessage(
|
||||
'f',
|
||||
'T',
|
||||
[],
|
||||
['z', 'y', 'x', 'w', 'v', 'u']
|
||||
));
|
||||
}
|
||||
|
||||
private function undefinedField($field, $type, $suggestedTypes, $suggestedFields, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
FieldsOnCorrectType::undefinedFieldMessage($field, $type, $suggestedTypes, $suggestedFields),
|
||||
[new SourceLocation($line, $column)]
|
||||
$this->assertEquals(
|
||||
$expected,
|
||||
FieldsOnCorrectType::undefinedFieldMessage(
|
||||
'f',
|
||||
'T',
|
||||
[],
|
||||
['z', 'y', 'x', 'w', 'v', 'u']
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\FragmentsOnCompositeTypes;
|
||||
class FragmentsOnCompositeTypesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Fragments on composite types
|
||||
|
||||
/**
|
||||
* @see it('object is valid fragment type')
|
||||
*/
|
||||
public function testObjectIsValidFragmentType() : void
|
||||
{
|
||||
$this->expectPassesRule(new FragmentsOnCompositeTypes, '
|
||||
$this->expectPassesRule(
|
||||
new FragmentsOnCompositeTypes(),
|
||||
'
|
||||
fragment validFragment on Dog {
|
||||
barks
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,11 +31,14 @@ class FragmentsOnCompositeTypesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInterfaceIsValidFragmentType() : void
|
||||
{
|
||||
$this->expectPassesRule(new FragmentsOnCompositeTypes, '
|
||||
$this->expectPassesRule(
|
||||
new FragmentsOnCompositeTypes(),
|
||||
'
|
||||
fragment validFragment on Pet {
|
||||
name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,13 +46,16 @@ class FragmentsOnCompositeTypesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testObjectIsValidInlineFragmentType() : void
|
||||
{
|
||||
$this->expectPassesRule(new FragmentsOnCompositeTypes, '
|
||||
$this->expectPassesRule(
|
||||
new FragmentsOnCompositeTypes(),
|
||||
'
|
||||
fragment validFragment on Pet {
|
||||
... on Dog {
|
||||
barks
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -52,13 +63,16 @@ class FragmentsOnCompositeTypesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInlineFragmentWithoutTypeIsValid() : void
|
||||
{
|
||||
$this->expectPassesRule(new FragmentsOnCompositeTypes, '
|
||||
$this->expectPassesRule(
|
||||
new FragmentsOnCompositeTypes(),
|
||||
'
|
||||
fragment validFragment on Pet {
|
||||
... {
|
||||
name
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,11 +80,14 @@ class FragmentsOnCompositeTypesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnionIsValidFragmentType() : void
|
||||
{
|
||||
$this->expectPassesRule(new FragmentsOnCompositeTypes, '
|
||||
$this->expectPassesRule(
|
||||
new FragmentsOnCompositeTypes(),
|
||||
'
|
||||
fragment validFragment on CatOrDog {
|
||||
__typename
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,56 +95,14 @@ class FragmentsOnCompositeTypesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testScalarIsInvalidFragmentType() : void
|
||||
{
|
||||
$this->expectFailsRule(new FragmentsOnCompositeTypes, '
|
||||
$this->expectFailsRule(
|
||||
new FragmentsOnCompositeTypes(),
|
||||
'
|
||||
fragment scalarFragment on Boolean {
|
||||
bad
|
||||
}
|
||||
',
|
||||
[$this->error('scalarFragment', 'Boolean', 2, 34)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('enum is invalid fragment type')
|
||||
*/
|
||||
public function testEnumIsInvalidFragmentType() : void
|
||||
{
|
||||
$this->expectFailsRule(new FragmentsOnCompositeTypes, '
|
||||
fragment scalarFragment on FurColor {
|
||||
bad
|
||||
}
|
||||
',
|
||||
[$this->error('scalarFragment', 'FurColor', 2, 34)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('input object is invalid fragment type')
|
||||
*/
|
||||
public function testInputObjectIsInvalidFragmentType() : void
|
||||
{
|
||||
$this->expectFailsRule(new FragmentsOnCompositeTypes, '
|
||||
fragment inputFragment on ComplexInput {
|
||||
stringField
|
||||
}
|
||||
',
|
||||
[$this->error('inputFragment', 'ComplexInput', 2, 33)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('scalar is invalid inline fragment type')
|
||||
*/
|
||||
public function testScalarIsInvalidInlineFragmentType() : void
|
||||
{
|
||||
$this->expectFailsRule(new FragmentsOnCompositeTypes, '
|
||||
fragment invalidFragment on Pet {
|
||||
... on String {
|
||||
barks
|
||||
}
|
||||
}
|
||||
',
|
||||
[FormattedError::create(
|
||||
FragmentsOnCompositeTypes::inlineFragmentOnNonCompositeErrorMessage('String'),
|
||||
[new SourceLocation(3, 16)]
|
||||
)]
|
||||
[$this->error('scalarFragment', 'Boolean', 2, 34)]
|
||||
);
|
||||
}
|
||||
|
||||
@ -135,7 +110,61 @@ class FragmentsOnCompositeTypesTest extends ValidatorTestCase
|
||||
{
|
||||
return FormattedError::create(
|
||||
FragmentsOnCompositeTypes::fragmentOnNonCompositeErrorMessage($fragName, $typeName),
|
||||
[ new SourceLocation($line, $column) ]
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('enum is invalid fragment type')
|
||||
*/
|
||||
public function testEnumIsInvalidFragmentType() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new FragmentsOnCompositeTypes(),
|
||||
'
|
||||
fragment scalarFragment on FurColor {
|
||||
bad
|
||||
}
|
||||
',
|
||||
[$this->error('scalarFragment', 'FurColor', 2, 34)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('input object is invalid fragment type')
|
||||
*/
|
||||
public function testInputObjectIsInvalidFragmentType() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new FragmentsOnCompositeTypes(),
|
||||
'
|
||||
fragment inputFragment on ComplexInput {
|
||||
stringField
|
||||
}
|
||||
',
|
||||
[$this->error('inputFragment', 'ComplexInput', 2, 33)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('scalar is invalid inline fragment type')
|
||||
*/
|
||||
public function testScalarIsInvalidInlineFragmentType() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new FragmentsOnCompositeTypes(),
|
||||
'
|
||||
fragment invalidFragment on Pet {
|
||||
... on String {
|
||||
barks
|
||||
}
|
||||
}
|
||||
',
|
||||
[FormattedError::create(
|
||||
FragmentsOnCompositeTypes::inlineFragmentOnNonCompositeErrorMessage('String'),
|
||||
[new SourceLocation(3, 16)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\KnownArgumentNames;
|
||||
class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Known argument names:
|
||||
|
||||
/**
|
||||
* @see it('single arg is known')
|
||||
*/
|
||||
public function testSingleArgIsKnown() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
fragment argOnRequiredArg on Dog {
|
||||
doesKnowCommand(dogCommand: SIT)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,11 +31,14 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleArgsAreKnown() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
fragment multipleArgs on ComplicatedArgs {
|
||||
multipleReqs(req1: 1, req2: 2)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,11 +46,14 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testIgnoresArgsOfUnknownFields() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
fragment argOnUnknownField on Dog {
|
||||
unknownField(unknownArg: SIT)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,11 +61,14 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleArgsInReverseOrderAreKnown() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
fragment multipleArgsReverseOrder on ComplicatedArgs {
|
||||
multipleReqs(req2: 2, req1: 1)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,11 +76,14 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoArgsOnOptionalArg() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
fragment noArgOnOptionalArg on Dog {
|
||||
isHousetrained
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -74,7 +91,9 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testArgsAreKnownDeeply() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
{
|
||||
dog {
|
||||
doesKnowCommand(dogCommand: SIT)
|
||||
@ -87,7 +106,8 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -95,11 +115,14 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDirectiveArgsAreKnown() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
{
|
||||
dog @skip(if: true)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -107,13 +130,25 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUndirectiveArgsAreInvalid() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownArgumentNames, '
|
||||
$this->expectFailsRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
{
|
||||
dog @skip(unless: true)
|
||||
}
|
||||
', [
|
||||
$this->unknownDirectiveArg('unless', 'skip', [], 3, 19),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unknownDirectiveArg('unless', 'skip', [], 3, 19),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function unknownDirectiveArg($argName, $directiveName, $suggestedArgs, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownArgumentNames::unknownDirectiveArgMessage($argName, $directiveName, $suggestedArgs),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -121,13 +156,17 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMisspelledDirectiveArgsAreReported() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownArgumentNames, '
|
||||
$this->expectFailsRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
{
|
||||
dog @skip(iff: true)
|
||||
}
|
||||
', [
|
||||
$this->unknownDirectiveArg('iff', 'skip', ['if'], 3, 19),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unknownDirectiveArg('iff', 'skip', ['if'], 3, 19),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -135,13 +174,25 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInvalidArgName() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownArgumentNames, '
|
||||
$this->expectFailsRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
fragment invalidArgName on Dog {
|
||||
doesKnowCommand(unknown: true)
|
||||
}
|
||||
', [
|
||||
$this->unknownArg('unknown', 'doesKnowCommand', 'Dog', [],3, 25),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unknownArg('unknown', 'doesKnowCommand', 'Dog', [], 3, 25),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function unknownArg($argName, $fieldName, $typeName, $suggestedArgs, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownArgumentNames::unknownArgMessage($argName, $fieldName, $typeName, $suggestedArgs),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -149,13 +200,17 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMisspelledArgNameIsReported() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownArgumentNames, '
|
||||
$this->expectFailsRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
fragment invalidArgName on Dog {
|
||||
doesKnowCommand(dogcommand: true)
|
||||
}
|
||||
', [
|
||||
$this->unknownArg('dogcommand', 'doesKnowCommand', 'Dog', ['dogCommand'],3, 25),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unknownArg('dogcommand', 'doesKnowCommand', 'Dog', ['dogCommand'], 3, 25),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,14 +218,18 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnknownArgsAmongstKnownArgs() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownArgumentNames, '
|
||||
$this->expectFailsRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
fragment oneGoodArgOneInvalidArg on Dog {
|
||||
doesKnowCommand(whoknows: 1, dogCommand: SIT, unknown: true)
|
||||
}
|
||||
', [
|
||||
$this->unknownArg('whoknows', 'doesKnowCommand', 'Dog', [], 3, 25),
|
||||
$this->unknownArg('unknown', 'doesKnowCommand', 'Dog', [], 3, 55),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unknownArg('whoknows', 'doesKnowCommand', 'Dog', [], 3, 25),
|
||||
$this->unknownArg('unknown', 'doesKnowCommand', 'Dog', [], 3, 55),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -178,7 +237,9 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnknownArgsDeeply() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownArgumentNames, '
|
||||
$this->expectFailsRule(
|
||||
new KnownArgumentNames(),
|
||||
'
|
||||
{
|
||||
dog {
|
||||
doesKnowCommand(unknown: true)
|
||||
@ -191,25 +252,11 @@ class KnownArgumentNamesTest extends ValidatorTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
', [
|
||||
$this->unknownArg('unknown', 'doesKnowCommand', 'Dog', [], 4, 27),
|
||||
$this->unknownArg('unknown', 'doesKnowCommand', 'Dog', [], 9, 31),
|
||||
]);
|
||||
}
|
||||
|
||||
private function unknownArg($argName, $fieldName, $typeName, $suggestedArgs, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownArgumentNames::unknownArgMessage($argName, $fieldName, $typeName, $suggestedArgs),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
private function unknownDirectiveArg($argName, $directiveName, $suggestedArgs, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownArgumentNames::unknownDirectiveArgMessage($argName, $directiveName, $suggestedArgs),
|
||||
[new SourceLocation($line, $column)]
|
||||
',
|
||||
[
|
||||
$this->unknownArg('unknown', 'doesKnowCommand', 'Dog', [], 4, 27),
|
||||
$this->unknownArg('unknown', 'doesKnowCommand', 'Dog', [], 9, 31),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,13 +11,14 @@ use GraphQL\Validator\Rules\KnownDirectives;
|
||||
class KnownDirectivesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Known directives
|
||||
|
||||
/**
|
||||
* @see it('with no directives')
|
||||
*/
|
||||
public function testWithNoDirectives() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownDirectives, '
|
||||
$this->expectPassesRule(
|
||||
new KnownDirectives(),
|
||||
'
|
||||
query Foo {
|
||||
name
|
||||
...Frag
|
||||
@ -23,7 +27,8 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
fragment Frag on Dog {
|
||||
name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,7 +36,9 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testWithKnownDirectives() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownDirectives, '
|
||||
$this->expectPassesRule(
|
||||
new KnownDirectives(),
|
||||
'
|
||||
{
|
||||
dog @include(if: true) {
|
||||
name
|
||||
@ -40,7 +47,8 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
name
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,15 +56,25 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testWithUnknownDirective() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownDirectives, '
|
||||
$this->expectFailsRule(
|
||||
new KnownDirectives(),
|
||||
'
|
||||
{
|
||||
dog @unknown(directive: "value") {
|
||||
name
|
||||
}
|
||||
}
|
||||
', [
|
||||
$this->unknownDirective('unknown', 3, 13)
|
||||
]);
|
||||
',
|
||||
[$this->unknownDirective('unknown', 3, 13)]
|
||||
);
|
||||
}
|
||||
|
||||
private function unknownDirective($directiveName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownDirectives::unknownDirectiveMessage($directiveName),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -64,7 +82,9 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testWithManyUnknownDirectives() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownDirectives, '
|
||||
$this->expectFailsRule(
|
||||
new KnownDirectives(),
|
||||
'
|
||||
{
|
||||
dog @unknown(directive: "value") {
|
||||
name
|
||||
@ -76,11 +96,13 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
', [
|
||||
$this->unknownDirective('unknown', 3, 13),
|
||||
$this->unknownDirective('unknown', 6, 15),
|
||||
$this->unknownDirective('unknown', 8, 16)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unknownDirective('unknown', 3, 13),
|
||||
$this->unknownDirective('unknown', 6, 15),
|
||||
$this->unknownDirective('unknown', 8, 16),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,7 +110,9 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testWithWellPlacedDirectives() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownDirectives, '
|
||||
$this->expectPassesRule(
|
||||
new KnownDirectives(),
|
||||
'
|
||||
query Foo @onQuery {
|
||||
name @include(if: true)
|
||||
...Frag @include(if: true)
|
||||
@ -99,15 +123,20 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
mutation Bar @onMutation {
|
||||
someField
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
// within schema language
|
||||
|
||||
/**
|
||||
* @see it('with misplaced directives')
|
||||
*/
|
||||
public function testWithMisplacedDirectives() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownDirectives, '
|
||||
$this->expectFailsRule(
|
||||
new KnownDirectives(),
|
||||
'
|
||||
query Foo @include(if: true) {
|
||||
name @onQuery
|
||||
...Frag @onQuery
|
||||
@ -116,22 +145,32 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
mutation Bar @onQuery {
|
||||
someField
|
||||
}
|
||||
', [
|
||||
$this->misplacedDirective('include', 'QUERY', 2, 17),
|
||||
$this->misplacedDirective('onQuery', 'FIELD', 3, 14),
|
||||
$this->misplacedDirective('onQuery', 'FRAGMENT_SPREAD', 4, 17),
|
||||
$this->misplacedDirective('onQuery', 'MUTATION', 7, 20),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->misplacedDirective('include', 'QUERY', 2, 17),
|
||||
$this->misplacedDirective('onQuery', 'FIELD', 3, 14),
|
||||
$this->misplacedDirective('onQuery', 'FRAGMENT_SPREAD', 4, 17),
|
||||
$this->misplacedDirective('onQuery', 'MUTATION', 7, 20),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// within schema language
|
||||
private function misplacedDirective($directiveName, $placement, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownDirectives::misplacedDirectiveMessage($directiveName, $placement),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('with well placed directives')
|
||||
*/
|
||||
public function testWSLWithWellPlacedDirectives() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownDirectives, '
|
||||
$this->expectPassesRule(
|
||||
new KnownDirectives(),
|
||||
'
|
||||
type MyObj implements MyInterface @onObject {
|
||||
myField(myArg: Int @onArgumentDefinition): String @onFieldDefinition
|
||||
}
|
||||
@ -167,7 +206,8 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
schema @onSchema {
|
||||
query: MyQuery
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,7 +215,9 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testWSLWithMisplacedDirectives() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownDirectives, '
|
||||
$this->expectFailsRule(
|
||||
new KnownDirectives(),
|
||||
'
|
||||
type MyObj implements MyInterface @onInterface {
|
||||
myField(myArg: Int @onInputFieldDefinition): String @onInputFieldDefinition
|
||||
}
|
||||
@ -217,20 +259,4 @@ class KnownDirectivesTest extends ValidatorTestCase
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function unknownDirective($directiveName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownDirectives::unknownDirectiveMessage($directiveName),
|
||||
[ new SourceLocation($line, $column) ]
|
||||
);
|
||||
}
|
||||
|
||||
function misplacedDirective($directiveName, $placement, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownDirectives::misplacedDirectiveMessage($directiveName, $placement),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,20 +1,24 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Validator\Rules\KnownFragmentNames;
|
||||
use GraphQL\Error\FormattedError;
|
||||
use GraphQL\Language\SourceLocation;
|
||||
use GraphQL\Validator\Rules\KnownFragmentNames;
|
||||
|
||||
class KnownFragmentNamesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Known fragment names
|
||||
|
||||
/**
|
||||
* @see it('known fragment names are valid')
|
||||
*/
|
||||
public function testKnownFragmentNamesAreValid() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownFragmentNames, '
|
||||
$this->expectPassesRule(
|
||||
new KnownFragmentNames(),
|
||||
'
|
||||
{
|
||||
human(id: 4) {
|
||||
...HumanFields1
|
||||
@ -33,7 +37,8 @@ class KnownFragmentNamesTest extends ValidatorTestCase
|
||||
fragment HumanFields3 on Human {
|
||||
name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -41,7 +46,9 @@ class KnownFragmentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnknownFragmentNamesAreInvalid() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownFragmentNames, '
|
||||
$this->expectFailsRule(
|
||||
new KnownFragmentNames(),
|
||||
'
|
||||
{
|
||||
human(id: 4) {
|
||||
...UnknownFragment1
|
||||
@ -54,11 +61,13 @@ class KnownFragmentNamesTest extends ValidatorTestCase
|
||||
name
|
||||
...UnknownFragment3
|
||||
}
|
||||
', [
|
||||
$this->undefFrag('UnknownFragment1', 4, 14),
|
||||
$this->undefFrag('UnknownFragment2', 6, 16),
|
||||
$this->undefFrag('UnknownFragment3', 12, 12)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefFrag('UnknownFragment1', 4, 14),
|
||||
$this->undefFrag('UnknownFragment2', 6, 16),
|
||||
$this->undefFrag('UnknownFragment3', 12, 12),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function undefFrag($fragName, $line, $column)
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,13 +11,14 @@ use GraphQL\Validator\Rules\KnownTypeNames;
|
||||
class KnownTypeNamesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Known type names
|
||||
|
||||
/**
|
||||
* @see it('known type names are valid')
|
||||
*/
|
||||
public function testKnownTypeNamesAreValid() : void
|
||||
{
|
||||
$this->expectPassesRule(new KnownTypeNames, '
|
||||
$this->expectPassesRule(
|
||||
new KnownTypeNames(),
|
||||
'
|
||||
query Foo($var: String, $required: [String!]!) {
|
||||
user(id: 4) {
|
||||
pets { ... on Pet { name }, ...PetFields }
|
||||
@ -23,7 +27,8 @@ class KnownTypeNamesTest extends ValidatorTestCase
|
||||
fragment PetFields on Pet {
|
||||
name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,7 +36,9 @@ class KnownTypeNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnknownTypeNamesAreInvalid() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownTypeNames, '
|
||||
$this->expectFailsRule(
|
||||
new KnownTypeNames(),
|
||||
'
|
||||
query Foo($var: JumbledUpLetters) {
|
||||
user(id: 4) {
|
||||
name
|
||||
@ -41,11 +48,21 @@ class KnownTypeNamesTest extends ValidatorTestCase
|
||||
fragment PetFields on Peettt {
|
||||
name
|
||||
}
|
||||
', [
|
||||
$this->unknownType('JumbledUpLetters', [], 2, 23),
|
||||
$this->unknownType('Badger', [], 5, 25),
|
||||
$this->unknownType('Peettt', ['Pet'], 8, 29)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unknownType('JumbledUpLetters', [], 2, 23),
|
||||
$this->unknownType('Badger', [], 5, 25),
|
||||
$this->unknownType('Peettt', ['Pet'], 8, 29),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function unknownType($typeName, $suggestedTypes, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownTypeNames::unknownTypeMessage($typeName, $suggestedTypes),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -53,7 +70,9 @@ class KnownTypeNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testIgnoresTypeDefinitions() : void
|
||||
{
|
||||
$this->expectFailsRule(new KnownTypeNames, '
|
||||
$this->expectFailsRule(
|
||||
new KnownTypeNames(),
|
||||
'
|
||||
type NotInTheSchema {
|
||||
field: FooBar
|
||||
}
|
||||
@ -69,16 +88,10 @@ class KnownTypeNamesTest extends ValidatorTestCase
|
||||
id
|
||||
}
|
||||
}
|
||||
', [
|
||||
$this->unknownType('NotInTheSchema', [], 12, 23),
|
||||
]);
|
||||
}
|
||||
|
||||
private function unknownType($typeName, $suggestedTypes, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
KnownTypeNames::unknownTypeMessage($typeName, $suggestedTypes),
|
||||
[new SourceLocation($line, $column)]
|
||||
',
|
||||
[
|
||||
$this->unknownType('NotInTheSchema', [], 12, 23),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\LoneAnonymousOperation;
|
||||
class LoneAnonymousOperationTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Anonymous operation must be alone
|
||||
|
||||
/**
|
||||
* @see it('no operations')
|
||||
*/
|
||||
public function testNoOperations() : void
|
||||
{
|
||||
$this->expectPassesRule(new LoneAnonymousOperation, '
|
||||
$this->expectPassesRule(
|
||||
new LoneAnonymousOperation(),
|
||||
'
|
||||
fragment fragA on Type {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,11 +31,14 @@ class LoneAnonymousOperationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testOneAnonOperation() : void
|
||||
{
|
||||
$this->expectPassesRule(new LoneAnonymousOperation, '
|
||||
$this->expectPassesRule(
|
||||
new LoneAnonymousOperation(),
|
||||
'
|
||||
{
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,7 +46,9 @@ class LoneAnonymousOperationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleNamedOperations() : void
|
||||
{
|
||||
$this->expectPassesRule(new LoneAnonymousOperation, '
|
||||
$this->expectPassesRule(
|
||||
new LoneAnonymousOperation(),
|
||||
'
|
||||
query Foo {
|
||||
field
|
||||
}
|
||||
@ -46,7 +56,8 @@ class LoneAnonymousOperationTest extends ValidatorTestCase
|
||||
query Bar {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -54,14 +65,17 @@ class LoneAnonymousOperationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAnonOperationWithFragment() : void
|
||||
{
|
||||
$this->expectPassesRule(new LoneAnonymousOperation, '
|
||||
$this->expectPassesRule(
|
||||
new LoneAnonymousOperation(),
|
||||
'
|
||||
{
|
||||
...Foo
|
||||
}
|
||||
fragment Foo on Type {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -69,51 +83,21 @@ class LoneAnonymousOperationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleAnonOperations() : void
|
||||
{
|
||||
$this->expectFailsRule(new LoneAnonymousOperation, '
|
||||
$this->expectFailsRule(
|
||||
new LoneAnonymousOperation(),
|
||||
'
|
||||
{
|
||||
fieldA
|
||||
}
|
||||
{
|
||||
fieldB
|
||||
}
|
||||
', [
|
||||
$this->anonNotAlone(2, 7),
|
||||
$this->anonNotAlone(5, 7)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('anon operation with a mutation')
|
||||
*/
|
||||
public function testAnonOperationWithMutation() : void
|
||||
{
|
||||
$this->expectFailsRule(new LoneAnonymousOperation, '
|
||||
{
|
||||
fieldA
|
||||
}
|
||||
mutation Foo {
|
||||
fieldB
|
||||
}
|
||||
', [
|
||||
$this->anonNotAlone(2, 7)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('anon operation with a subscription')
|
||||
*/
|
||||
public function testAnonOperationWithSubscription() : void
|
||||
{
|
||||
$this->expectFailsRule(new LoneAnonymousOperation, '
|
||||
{
|
||||
fieldA
|
||||
}
|
||||
subscription Foo {
|
||||
fieldB
|
||||
}
|
||||
', [
|
||||
$this->anonNotAlone(2, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->anonNotAlone(2, 7),
|
||||
$this->anonNotAlone(5, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function anonNotAlone($line, $column)
|
||||
@ -122,6 +106,47 @@ class LoneAnonymousOperationTest extends ValidatorTestCase
|
||||
LoneAnonymousOperation::anonOperationNotAloneMessage(),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('anon operation with a mutation')
|
||||
*/
|
||||
public function testAnonOperationWithMutation() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new LoneAnonymousOperation(),
|
||||
'
|
||||
{
|
||||
fieldA
|
||||
}
|
||||
mutation Foo {
|
||||
fieldB
|
||||
}
|
||||
',
|
||||
[
|
||||
$this->anonNotAlone(2, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('anon operation with a subscription')
|
||||
*/
|
||||
public function testAnonOperationWithSubscription() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new LoneAnonymousOperation(),
|
||||
'
|
||||
{
|
||||
fieldA
|
||||
}
|
||||
subscription Foo {
|
||||
fieldB
|
||||
}
|
||||
',
|
||||
[
|
||||
$this->anonNotAlone(2, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,16 +11,18 @@ use GraphQL\Validator\Rules\NoFragmentCycles;
|
||||
class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: No circular fragment spreads
|
||||
|
||||
/**
|
||||
* @see it('single reference is valid')
|
||||
*/
|
||||
public function testSingleReferenceIsValid() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoFragmentCycles(), '
|
||||
$this->expectPassesRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Dog { ...fragB }
|
||||
fragment fragB on Dog { name }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,10 +30,13 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSpreadingTwiceIsNotCircular() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoFragmentCycles, '
|
||||
$this->expectPassesRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Dog { ...fragB, ...fragB }
|
||||
fragment fragB on Dog { name }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -36,11 +44,14 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSpreadingTwiceIndirectlyIsNotCircular() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoFragmentCycles, '
|
||||
$this->expectPassesRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Dog { ...fragB, ...fragC }
|
||||
fragment fragB on Dog { ...fragC }
|
||||
fragment fragC on Dog { name }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -48,7 +59,9 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDoubleSpreadWithinAbstractTypes() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoFragmentCycles, '
|
||||
$this->expectPassesRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment nameFragment on Pet {
|
||||
... on Dog { name }
|
||||
... on Cat { name }
|
||||
@ -58,7 +71,8 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
... on Dog { ...nameFragment }
|
||||
... on Cat { ...nameFragment }
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,11 +80,14 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDoesNotFalsePositiveOnUnknownFragment() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoFragmentCycles, '
|
||||
$this->expectPassesRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment nameFragment on Pet {
|
||||
...UnknownFragment
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,11 +95,23 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSpreadingRecursivelyWithinFieldFails() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Human { relatives { ...fragA } },
|
||||
', [
|
||||
$this->cycleError('fragA', [], 2, 45)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->cycleError('fragA', [], 2, 45),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function cycleError($fargment, $spreadNames, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage($fargment, $spreadNames),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,11 +119,15 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoSpreadingItselfDirectly() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Dog { ...fragA }
|
||||
', [
|
||||
$this->cycleError('fragA', [], 2, 31)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->cycleError('fragA', [], 2, 31),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -102,15 +135,19 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoSpreadingItselfDirectlyWithinInlineFragment() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Pet {
|
||||
... on Dog {
|
||||
...fragA
|
||||
}
|
||||
}
|
||||
', [
|
||||
$this->cycleError('fragA', [], 4, 11)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->cycleError('fragA', [], 4, 11),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -118,15 +155,19 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoSpreadingItselfIndirectly() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Dog { ...fragB }
|
||||
fragment fragB on Dog { ...fragA }
|
||||
', [
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragB']),
|
||||
[ new SourceLocation(2, 31), new SourceLocation(3, 31) ]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragB']),
|
||||
[new SourceLocation(2, 31), new SourceLocation(3, 31)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -134,15 +175,19 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoSpreadingItselfIndirectlyReportsOppositeOrder() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragB on Dog { ...fragA }
|
||||
fragment fragA on Dog { ...fragB }
|
||||
', [
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragB', ['fragA']),
|
||||
[new SourceLocation(2, 31), new SourceLocation(3, 31)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragB', ['fragA']),
|
||||
[new SourceLocation(2, 31), new SourceLocation(3, 31)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -150,7 +195,9 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoSpreadingItselfIndirectlyWithinInlineFragment() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Pet {
|
||||
... on Dog {
|
||||
...fragB
|
||||
@ -161,12 +208,14 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
...fragA
|
||||
}
|
||||
}
|
||||
', [
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragB']),
|
||||
[new SourceLocation(4, 11), new SourceLocation(9, 11)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragB']),
|
||||
[new SourceLocation(4, 11), new SourceLocation(9, 11)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -174,7 +223,9 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoSpreadingItselfDeeply() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Dog { ...fragB }
|
||||
fragment fragB on Dog { ...fragC }
|
||||
fragment fragC on Dog { ...fragO }
|
||||
@ -183,28 +234,30 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
fragment fragZ on Dog { ...fragO }
|
||||
fragment fragO on Dog { ...fragP }
|
||||
fragment fragP on Dog { ...fragA, ...fragX }
|
||||
', [
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', [ 'fragB', 'fragC', 'fragO', 'fragP' ]),
|
||||
[
|
||||
new SourceLocation(2, 31),
|
||||
new SourceLocation(3, 31),
|
||||
new SourceLocation(4, 31),
|
||||
new SourceLocation(8, 31),
|
||||
new SourceLocation(9, 31),
|
||||
]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragO', [ 'fragP', 'fragX', 'fragY', 'fragZ' ]),
|
||||
[
|
||||
new SourceLocation(8, 31),
|
||||
new SourceLocation(9, 41),
|
||||
new SourceLocation(5, 31),
|
||||
new SourceLocation(6, 31),
|
||||
new SourceLocation(7, 31),
|
||||
]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragB', 'fragC', 'fragO', 'fragP']),
|
||||
[
|
||||
new SourceLocation(2, 31),
|
||||
new SourceLocation(3, 31),
|
||||
new SourceLocation(4, 31),
|
||||
new SourceLocation(8, 31),
|
||||
new SourceLocation(9, 31),
|
||||
]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragO', ['fragP', 'fragX', 'fragY', 'fragZ']),
|
||||
[
|
||||
new SourceLocation(8, 31),
|
||||
new SourceLocation(9, 41),
|
||||
new SourceLocation(5, 31),
|
||||
new SourceLocation(6, 31),
|
||||
new SourceLocation(7, 31),
|
||||
]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -212,20 +265,24 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoSpreadingItselfDeeplyTwoPaths() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Dog { ...fragB, ...fragC }
|
||||
fragment fragB on Dog { ...fragA }
|
||||
fragment fragC on Dog { ...fragA }
|
||||
', [
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragB']),
|
||||
[new SourceLocation(2, 31), new SourceLocation(3, 31)]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragC']),
|
||||
[new SourceLocation(2, 41), new SourceLocation(4, 31)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragB']),
|
||||
[new SourceLocation(2, 31), new SourceLocation(3, 31)]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragC']),
|
||||
[new SourceLocation(2, 41), new SourceLocation(4, 31)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -233,20 +290,24 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoSpreadingItselfDeeplyTwoPathsTraverseOrder() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Dog { ...fragC }
|
||||
fragment fragB on Dog { ...fragC }
|
||||
fragment fragC on Dog { ...fragA, ...fragB }
|
||||
', [
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', [ 'fragC' ]),
|
||||
[new SourceLocation(2,31), new SourceLocation(4,31)]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragC', [ 'fragB' ]),
|
||||
[new SourceLocation(4, 41), new SourceLocation(3, 31)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragC']),
|
||||
[new SourceLocation(2, 31), new SourceLocation(4, 31)]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragC', ['fragB']),
|
||||
[new SourceLocation(4, 41), new SourceLocation(3, 31)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -254,35 +315,31 @@ class NoFragmentCyclesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoSpreadingItselfDeeplyAndImmediately() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoFragmentCycles, '
|
||||
$this->expectFailsRule(
|
||||
new NoFragmentCycles(),
|
||||
'
|
||||
fragment fragA on Dog { ...fragB }
|
||||
fragment fragB on Dog { ...fragB, ...fragC }
|
||||
fragment fragC on Dog { ...fragA, ...fragB }
|
||||
', [
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragB', []),
|
||||
[new SourceLocation(3, 31)]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', [ 'fragB', 'fragC' ]),
|
||||
[
|
||||
new SourceLocation(2, 31),
|
||||
new SourceLocation(3, 41),
|
||||
new SourceLocation(4, 31)
|
||||
]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragB', [ 'fragC' ]),
|
||||
[new SourceLocation(3, 41), new SourceLocation(4, 41)]
|
||||
)
|
||||
]);
|
||||
}
|
||||
|
||||
private function cycleError($fargment, $spreadNames, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage($fargment, $spreadNames),
|
||||
[new SourceLocation($line, $column)]
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragB', []),
|
||||
[new SourceLocation(3, 31)]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragA', ['fragB', 'fragC']),
|
||||
[
|
||||
new SourceLocation(2, 31),
|
||||
new SourceLocation(3, 41),
|
||||
new SourceLocation(4, 31),
|
||||
]
|
||||
),
|
||||
FormattedError::create(
|
||||
NoFragmentCycles::cycleErrorMessage('fragB', ['fragC']),
|
||||
[new SourceLocation(3, 41), new SourceLocation(4, 41)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\NoUndefinedVariables;
|
||||
class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: No undefined variables
|
||||
|
||||
/**
|
||||
* @see it('all variables defined')
|
||||
*/
|
||||
public function testAllVariablesDefined() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUndefinedVariables(), '
|
||||
$this->expectPassesRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
field(a: $a, b: $b, c: $c)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,7 +31,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAllVariablesDeeplyDefined() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUndefinedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
field(a: $a) {
|
||||
field(b: $b) {
|
||||
@ -34,7 +41,8 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +50,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAllVariablesDeeplyInInlineFragmentsDefined() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUndefinedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
... on Type {
|
||||
field(a: $a) {
|
||||
@ -54,7 +64,8 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +73,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAllVariablesInFragmentsDeeplyDefined() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUndefinedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -79,7 +92,8 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
fragment FragC on Type {
|
||||
field(c: $c)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -88,7 +102,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
public function testVariableWithinSingleFragmentDefinedInMultipleOperations() : void
|
||||
{
|
||||
// variable within single fragment defined in multiple operations
|
||||
$this->expectPassesRule(new NoUndefinedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -98,7 +114,8 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
fragment FragA on Type {
|
||||
field(a: $a)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -106,7 +123,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableWithinFragmentsDefinedInOperations() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUndefinedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -119,7 +138,8 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
fragment FragB on Type {
|
||||
field(b: $b)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -127,7 +147,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableWithinRecursiveFragmentDefined() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUndefinedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -136,7 +158,8 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
...FragA
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,13 +167,31 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableNotDefined() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
field(a: $a, b: $b, c: $c, d: $d)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('d', 3, 39, 'Foo', 2, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefVar('d', 3, 39, 'Foo', 2, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function undefVar($varName, $line, $column, $opName = null, $l2 = null, $c2 = null)
|
||||
{
|
||||
$locs = [new SourceLocation($line, $column)];
|
||||
|
||||
if ($l2 && $c2) {
|
||||
$locs[] = new SourceLocation($l2, $c2);
|
||||
}
|
||||
|
||||
return FormattedError::create(
|
||||
NoUndefinedVariables::undefinedVarMessage($varName, $opName),
|
||||
$locs
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,13 +199,17 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableNotDefinedByUnNamedQuery() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
{
|
||||
field(a: $a)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('a', 3, 18, '', 2, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefVar('a', 3, 18, '', 2, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -172,14 +217,18 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleVariablesNotDefined() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($b: String) {
|
||||
field(a: $a, b: $b, c: $c)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('a', 3, 18, 'Foo', 2, 7),
|
||||
$this->undefVar('c', 3, 32, 'Foo', 2, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefVar('a', 3, 18, 'Foo', 2, 7),
|
||||
$this->undefVar('c', 3, 32, 'Foo', 2, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -187,16 +236,20 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableInFragmentNotDefinedByUnNamedQuery() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
{
|
||||
...FragA
|
||||
}
|
||||
fragment FragA on Type {
|
||||
field(a: $a)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('a', 6, 18, '', 2, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefVar('a', 6, 18, '', 2, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -204,7 +257,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableInFragmentNotDefinedByOperation() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -221,9 +276,11 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
fragment FragC on Type {
|
||||
field(c: $c)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('c', 16, 18, 'Foo', 2, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefVar('c', 16, 18, 'Foo', 2, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -231,7 +288,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleVariablesInFragmentsNotDefined() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($b: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -248,10 +307,12 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
fragment FragC on Type {
|
||||
field(c: $c)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('a', 6, 18, 'Foo', 2, 7),
|
||||
$this->undefVar('c', 16, 18, 'Foo', 2, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefVar('a', 6, 18, 'Foo', 2, 7),
|
||||
$this->undefVar('c', 16, 18, 'Foo', 2, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -259,7 +320,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSingleVariableInFragmentNotDefinedByMultipleOperations() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($a: String) {
|
||||
...FragAB
|
||||
}
|
||||
@ -269,10 +332,12 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
fragment FragAB on Type {
|
||||
field(a: $a, b: $b)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('b', 9, 25, 'Foo', 2, 7),
|
||||
$this->undefVar('b', 9, 25, 'Bar', 5, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefVar('b', 9, 25, 'Foo', 2, 7),
|
||||
$this->undefVar('b', 9, 25, 'Bar', 5, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -280,7 +345,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariablesInFragmentNotDefinedByMultipleOperations() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($b: String) {
|
||||
...FragAB
|
||||
}
|
||||
@ -290,10 +357,12 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
fragment FragAB on Type {
|
||||
field(a: $a, b: $b)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('a', 9, 18, 'Foo', 2, 7),
|
||||
$this->undefVar('b', 9, 25, 'Bar', 5, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefVar('a', 9, 18, 'Foo', 2, 7),
|
||||
$this->undefVar('b', 9, 25, 'Bar', 5, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -301,7 +370,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableInFragmentUsedByOtherOperation() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($b: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -314,10 +385,12 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
fragment FragB on Type {
|
||||
field(b: $b)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('a', 9, 18, 'Foo', 2, 7),
|
||||
$this->undefVar('b', 12, 18, 'Bar', 5, 7)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->undefVar('a', 9, 18, 'Foo', 2, 7),
|
||||
$this->undefVar('b', 12, 18, 'Bar', 5, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -325,7 +398,9 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleUndefinedVariablesProduceMultipleErrors() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUndefinedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUndefinedVariables(),
|
||||
'
|
||||
query Foo($b: String) {
|
||||
...FragAB
|
||||
}
|
||||
@ -340,28 +415,15 @@ class NoUndefinedVariablesTest extends ValidatorTestCase
|
||||
fragment FragC on Type {
|
||||
field2(c: $c)
|
||||
}
|
||||
', [
|
||||
$this->undefVar('a', 9, 19, 'Foo', 2, 7),
|
||||
$this->undefVar('a', 11, 19, 'Foo', 2, 7),
|
||||
$this->undefVar('c', 14, 19, 'Foo', 2, 7),
|
||||
$this->undefVar('b', 9, 26, 'Bar', 5, 7),
|
||||
$this->undefVar('b', 11, 26, 'Bar', 5, 7),
|
||||
$this->undefVar('c', 14, 19, 'Bar', 5, 7),
|
||||
]);
|
||||
}
|
||||
|
||||
|
||||
private function undefVar($varName, $line, $column, $opName = null, $l2 = null, $c2 = null)
|
||||
{
|
||||
$locs = [new SourceLocation($line, $column)];
|
||||
|
||||
if ($l2 && $c2) {
|
||||
$locs[] = new SourceLocation($l2, $c2);
|
||||
}
|
||||
|
||||
return FormattedError::create(
|
||||
NoUndefinedVariables::undefinedVarMessage($varName, $opName),
|
||||
$locs
|
||||
',
|
||||
[
|
||||
$this->undefVar('a', 9, 19, 'Foo', 2, 7),
|
||||
$this->undefVar('a', 11, 19, 'Foo', 2, 7),
|
||||
$this->undefVar('c', 14, 19, 'Foo', 2, 7),
|
||||
$this->undefVar('b', 9, 26, 'Bar', 5, 7),
|
||||
$this->undefVar('b', 11, 26, 'Bar', 5, 7),
|
||||
$this->undefVar('c', 14, 19, 'Bar', 5, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,13 +11,14 @@ use GraphQL\Validator\Rules\NoUnusedFragments;
|
||||
class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: No unused fragments
|
||||
|
||||
/**
|
||||
* @see it('all fragment names are used')
|
||||
*/
|
||||
public function testAllFragmentNamesAreUsed() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUnusedFragments(), '
|
||||
$this->expectPassesRule(
|
||||
new NoUnusedFragments(),
|
||||
'
|
||||
{
|
||||
human(id: 4) {
|
||||
...HumanFields1
|
||||
@ -33,7 +37,8 @@ class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
fragment HumanFields3 on Human {
|
||||
name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -41,7 +46,9 @@ class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAllFragmentNamesAreUsedByMultipleOperations() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUnusedFragments, '
|
||||
$this->expectPassesRule(
|
||||
new NoUnusedFragments(),
|
||||
'
|
||||
query Foo {
|
||||
human(id: 4) {
|
||||
...HumanFields1
|
||||
@ -62,7 +69,8 @@ class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
fragment HumanFields3 on Human {
|
||||
name
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,7 +78,9 @@ class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testContainsUnknownFragments() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUnusedFragments, '
|
||||
$this->expectFailsRule(
|
||||
new NoUnusedFragments(),
|
||||
'
|
||||
query Foo {
|
||||
human(id: 4) {
|
||||
...HumanFields1
|
||||
@ -97,10 +107,20 @@ class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
fragment Unused2 on Human {
|
||||
name
|
||||
}
|
||||
', [
|
||||
$this->unusedFrag('Unused1', 22, 7),
|
||||
$this->unusedFrag('Unused2', 25, 7),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unusedFrag('Unused1', 22, 7),
|
||||
$this->unusedFrag('Unused2', 25, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function unusedFrag($fragName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
NoUnusedFragments::unusedFragMessage($fragName),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,7 +128,9 @@ class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testContainsUnknownFragmentsWithRefCycle() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUnusedFragments, '
|
||||
$this->expectFailsRule(
|
||||
new NoUnusedFragments(),
|
||||
'
|
||||
query Foo {
|
||||
human(id: 4) {
|
||||
...HumanFields1
|
||||
@ -137,10 +159,12 @@ class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
name
|
||||
...Unused1
|
||||
}
|
||||
', [
|
||||
$this->unusedFrag('Unused1', 22, 7),
|
||||
$this->unusedFrag('Unused2', 26, 7),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unusedFrag('Unused1', 22, 7),
|
||||
$this->unusedFrag('Unused2', 26, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -148,8 +172,9 @@ class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testContainsUnknownAndUndefFragments() : void
|
||||
{
|
||||
|
||||
$this->expectFailsRule(new NoUnusedFragments, '
|
||||
$this->expectFailsRule(
|
||||
new NoUnusedFragments(),
|
||||
'
|
||||
query Foo {
|
||||
human(id: 4) {
|
||||
...bar
|
||||
@ -158,16 +183,10 @@ class NoUnusedFragmentsTest extends ValidatorTestCase
|
||||
fragment foo on Human {
|
||||
name
|
||||
}
|
||||
', [
|
||||
$this->unusedFrag('foo', 7, 7),
|
||||
]);
|
||||
}
|
||||
|
||||
private function unusedFrag($fragName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
NoUnusedFragments::unusedFragMessage($fragName),
|
||||
[new SourceLocation($line, $column)]
|
||||
',
|
||||
[
|
||||
$this->unusedFrag('foo', 7, 7),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\NoUnusedVariables;
|
||||
class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: No unused variables
|
||||
|
||||
/**
|
||||
* @see it('uses all variables')
|
||||
*/
|
||||
public function testUsesAllVariables() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUnusedVariables(), '
|
||||
$this->expectPassesRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
field(a: $a, b: $b, c: $c)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,7 +31,9 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUsesAllVariablesDeeply() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUnusedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
field(a: $a) {
|
||||
field(b: $b) {
|
||||
@ -34,7 +41,8 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +50,9 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUsesAllVariablesDeeplyInInlineFragments() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUnusedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
... on Type {
|
||||
field(a: $a) {
|
||||
@ -54,7 +64,8 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
}
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,7 +73,9 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUsesAllVariablesInFragments() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUnusedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -79,7 +92,8 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
fragment FragC on Type {
|
||||
field(c: $c)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,7 +101,9 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableUsedByFragmentInMultipleOperations() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUnusedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($a: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -100,7 +116,8 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
fragment FragB on Type {
|
||||
field(b: $b)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -108,7 +125,9 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableUsedByRecursiveFragment() : void
|
||||
{
|
||||
$this->expectPassesRule(new NoUnusedVariables, '
|
||||
$this->expectPassesRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($a: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -117,7 +136,8 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
...FragA
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -125,13 +145,25 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableNotUsed() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUnusedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query ($a: String, $b: String, $c: String) {
|
||||
field(a: $a, b: $b)
|
||||
}
|
||||
', [
|
||||
$this->unusedVar('c', null, 2, 38)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unusedVar('c', null, 2, 38),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function unusedVar($varName, $opName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
NoUnusedVariables::unusedVariableMessage($varName, $opName),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -139,14 +171,18 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleVariablesNotUsed() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUnusedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
field(b: $b)
|
||||
}
|
||||
', [
|
||||
$this->unusedVar('a', 'Foo', 2, 17),
|
||||
$this->unusedVar('c', 'Foo', 2, 41)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unusedVar('a', 'Foo', 2, 17),
|
||||
$this->unusedVar('c', 'Foo', 2, 41),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -154,7 +190,9 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableNotUsedInFragments() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUnusedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -171,9 +209,11 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
fragment FragC on Type {
|
||||
field
|
||||
}
|
||||
', [
|
||||
$this->unusedVar('c', 'Foo', 2, 41)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unusedVar('c', 'Foo', 2, 41),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -181,7 +221,9 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleVariablesNotUsed2() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUnusedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($a: String, $b: String, $c: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -198,10 +240,12 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
fragment FragC on Type {
|
||||
field
|
||||
}
|
||||
', [
|
||||
$this->unusedVar('a', 'Foo', 2, 17),
|
||||
$this->unusedVar('c', 'Foo', 2, 41)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unusedVar('a', 'Foo', 2, 17),
|
||||
$this->unusedVar('c', 'Foo', 2, 41),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -209,7 +253,9 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableNotUsedByUnreferencedFragment() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUnusedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($b: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -219,9 +265,11 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
fragment FragB on Type {
|
||||
field(b: $b)
|
||||
}
|
||||
', [
|
||||
$this->unusedVar('b', 'Foo', 2, 17)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->unusedVar('b', 'Foo', 2, 17),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -229,7 +277,9 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testVariableNotUsedByFragmentUsedByOtherOperation() : void
|
||||
{
|
||||
$this->expectFailsRule(new NoUnusedVariables, '
|
||||
$this->expectFailsRule(
|
||||
new NoUnusedVariables(),
|
||||
'
|
||||
query Foo($b: String) {
|
||||
...FragA
|
||||
}
|
||||
@ -242,17 +292,11 @@ class NoUnusedVariablesTest extends ValidatorTestCase
|
||||
fragment FragB on Type {
|
||||
field(b: $b)
|
||||
}
|
||||
', [
|
||||
$this->unusedVar('b', 'Foo', 2, 17),
|
||||
$this->unusedVar('a', 'Bar', 5, 17)
|
||||
]);
|
||||
}
|
||||
|
||||
private function unusedVar($varName, $opName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
NoUnusedVariables::unusedVariableMessage($varName, $opName),
|
||||
[new SourceLocation($line, $column)]
|
||||
',
|
||||
[
|
||||
$this->unusedVar('b', 'Foo', 2, 17),
|
||||
$this->unusedVar('a', 'Bar', 5, 17),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,16 +11,18 @@ use GraphQL\Validator\Rules\PossibleFragmentSpreads;
|
||||
class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Possible fragment spreads
|
||||
|
||||
/**
|
||||
* @see it('of the same object')
|
||||
*/
|
||||
public function testOfTheSameObject() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads(), '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment objectWithinObject on Dog { ...dogFragment }
|
||||
fragment dogFragment on Dog { barkVolume }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,9 +30,12 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testOfTheSameObjectWithInlineFragment() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment objectWithinObjectAnon on Dog { ... on Dog { barkVolume } }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -35,10 +43,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testObjectIntoAnImplementedInterface() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment objectWithinInterface on Pet { ...dogFragment }
|
||||
fragment dogFragment on Dog { barkVolume }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,10 +57,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testObjectIntoContainingUnion() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment objectWithinUnion on CatOrDog { ...dogFragment }
|
||||
fragment dogFragment on Dog { barkVolume }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -57,10 +71,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnionIntoContainedObject() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment unionWithinObject on Dog { ...catOrDogFragment }
|
||||
fragment catOrDogFragment on CatOrDog { __typename }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -68,10 +85,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnionIntoOverlappingInterface() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment unionWithinInterface on Pet { ...catOrDogFragment }
|
||||
fragment catOrDogFragment on CatOrDog { __typename }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -79,10 +99,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnionIntoOverlappingUnion() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment unionWithinUnion on DogOrHuman { ...catOrDogFragment }
|
||||
fragment catOrDogFragment on CatOrDog { __typename }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -90,10 +113,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInterfaceIntoImplementedObject() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment interfaceWithinObject on Dog { ...petFragment }
|
||||
fragment petFragment on Pet { name }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,10 +127,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInterfaceIntoOverlappingInterface() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment interfaceWithinInterface on Pet { ...beingFragment }
|
||||
fragment beingFragment on Being { name }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -112,9 +141,12 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInterfaceIntoOverlappingInterfaceInInlineFragment() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment interfaceWithinInterface on Pet { ... on Being { name } }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -122,10 +154,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInterfaceIntoOverlappingUnion() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment interfaceWithinUnion on CatOrDog { ...petFragment }
|
||||
fragment petFragment on Pet { name }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -133,10 +168,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testIgnoresIncorrectTypeCaughtByFragmentsOnCompositeTypes() : void
|
||||
{
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment petFragment on Pet { ...badInADifferentWay }
|
||||
fragment badInADifferentWay on String { name }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -144,7 +182,9 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDifferentObjectIntoObject() : void
|
||||
{
|
||||
$this->expectFailsRule(new PossibleFragmentSpreads, '
|
||||
$this->expectFailsRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidObjectWithinObject on Cat { ...dogFragment }
|
||||
fragment dogFragment on Dog { barkVolume }
|
||||
',
|
||||
@ -152,12 +192,22 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
);
|
||||
}
|
||||
|
||||
private function error($fragName, $parentType, $fragType, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
PossibleFragmentSpreads::typeIncompatibleSpreadMessage($fragName, $parentType, $fragType),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('different object into object in inline fragment')
|
||||
*/
|
||||
public function testDifferentObjectIntoObjectInInlineFragment() : void
|
||||
{
|
||||
$this->expectFailsRule(new PossibleFragmentSpreads, '
|
||||
$this->expectFailsRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidObjectWithinObjectAnon on Cat {
|
||||
... on Dog { barkVolume }
|
||||
}
|
||||
@ -166,12 +216,22 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
);
|
||||
}
|
||||
|
||||
private function errorAnon($parentType, $fragType, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
PossibleFragmentSpreads::typeIncompatibleAnonSpreadMessage($parentType, $fragType),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('object into not implementing interface')
|
||||
*/
|
||||
public function testObjectIntoNotImplementingInterface() : void
|
||||
{
|
||||
$this->expectFailsRule(new PossibleFragmentSpreads, '
|
||||
$this->expectFailsRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidObjectWithinInterface on Pet { ...humanFragment }
|
||||
fragment humanFragment on Human { pets { name } }
|
||||
',
|
||||
@ -184,7 +244,9 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testObjectIntoNotContainingUnion() : void
|
||||
{
|
||||
$this->expectFailsRule(new PossibleFragmentSpreads, '
|
||||
$this->expectFailsRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidObjectWithinUnion on CatOrDog { ...humanFragment }
|
||||
fragment humanFragment on Human { pets { name } }
|
||||
',
|
||||
@ -197,7 +259,9 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnionIntoNotContainedObject() : void
|
||||
{
|
||||
$this->expectFailsRule(new PossibleFragmentSpreads, '
|
||||
$this->expectFailsRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidUnionWithinObject on Human { ...catOrDogFragment }
|
||||
fragment catOrDogFragment on CatOrDog { __typename }
|
||||
',
|
||||
@ -210,7 +274,9 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnionIntoNonOverlappingInterface() : void
|
||||
{
|
||||
$this->expectFailsRule(new PossibleFragmentSpreads, '
|
||||
$this->expectFailsRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidUnionWithinInterface on Pet { ...humanOrAlienFragment }
|
||||
fragment humanOrAlienFragment on HumanOrAlien { __typename }
|
||||
',
|
||||
@ -223,7 +289,9 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUnionIntoNonOverlappingUnion() : void
|
||||
{
|
||||
$this->expectFailsRule(new PossibleFragmentSpreads, '
|
||||
$this->expectFailsRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidUnionWithinUnion on CatOrDog { ...humanOrAlienFragment }
|
||||
fragment humanOrAlienFragment on HumanOrAlien { __typename }
|
||||
',
|
||||
@ -236,7 +304,9 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInterfaceIntoNonImplementingObject() : void
|
||||
{
|
||||
$this->expectFailsRule(new PossibleFragmentSpreads, '
|
||||
$this->expectFailsRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidInterfaceWithinObject on Cat { ...intelligentFragment }
|
||||
fragment intelligentFragment on Intelligent { iq }
|
||||
',
|
||||
@ -252,12 +322,15 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
// Ideally this should fail, but our new lazy schema doesn't scan through all types and fields
|
||||
// So we don't have enough knowledge to check interface intersection and always allow this to pass:
|
||||
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidInterfaceWithinInterface on Pet {
|
||||
...intelligentFragment
|
||||
}
|
||||
fragment intelligentFragment on Intelligent { iq }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -268,11 +341,14 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
// Ideally this should fail, but our new lazy schema doesn't scan through all types and fields
|
||||
// So we don't have enough knowledge to check interface intersection and always allow this to pass:
|
||||
|
||||
$this->expectPassesRule(new PossibleFragmentSpreads, '
|
||||
$this->expectPassesRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidInterfaceWithinInterfaceAnon on Pet {
|
||||
...on Intelligent { iq }
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -280,27 +356,13 @@ class PossibleFragmentSpreadsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInterfaceIntoNonOverlappingUnion() : void
|
||||
{
|
||||
$this->expectFailsRule(new PossibleFragmentSpreads, '
|
||||
$this->expectFailsRule(
|
||||
new PossibleFragmentSpreads(),
|
||||
'
|
||||
fragment invalidInterfaceWithinUnion on HumanOrAlien { ...petFragment }
|
||||
fragment petFragment on Pet { name }
|
||||
',
|
||||
[$this->error('petFragment', 'HumanOrAlien', 'Pet', 2, 62)]
|
||||
);
|
||||
}
|
||||
|
||||
private function error($fragName, $parentType, $fragType, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
PossibleFragmentSpreads::typeIncompatibleSpreadMessage($fragName, $parentType, $fragType),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
private function errorAnon($parentType, $fragType, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
PossibleFragmentSpreads::typeIncompatibleAnonSpreadMessage($parentType, $fragType),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,20 +11,22 @@ use GraphQL\Validator\Rules\ProvidedNonNullArguments;
|
||||
class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Provided required arguments
|
||||
|
||||
/**
|
||||
* @see it('ignores unknown arguments')
|
||||
*/
|
||||
public function testIgnoresUnknownArguments() : void
|
||||
{
|
||||
// ignores unknown arguments
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
dog {
|
||||
isHousetrained(unknownArgument: true)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
// Valid non-nullable value:
|
||||
@ -31,13 +36,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testArgOnOptionalArg() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
dog {
|
||||
isHousetrained(atOtherHomes: true)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -45,13 +53,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoArgOnOptionalArg() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
dog {
|
||||
isHousetrained
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -59,13 +70,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleArgs() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleReqs(req1: 1, req2: 2)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -73,13 +87,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleArgsReverseOrder() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleReqs(req2: 2, req1: 1)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,13 +104,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoArgsOnMultipleOptional() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleOpts
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,13 +121,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testOneArgOnMultipleOptional() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleOpts(opt1: 1)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,13 +138,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSecondArgOnMultipleOptional() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleOpts(opt2: 1)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -129,13 +155,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleReqsOnMixedList() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleOptAndReq(req1: 3, req2: 4)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,13 +172,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleReqsAndOneOptOnMixedList() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleOptAndReq(req1: 3, req2: 4, opt1: 5)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -157,13 +189,16 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAllReqsAndOptsOnMixedList() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleOptAndReq(req1: 3, req2: 4, opt1: 5, opt2: 6)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
// Invalid non-nullable value
|
||||
@ -173,15 +208,25 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMissingOneNonNullableArgument() : void
|
||||
{
|
||||
$this->expectFailsRule(new ProvidedNonNullArguments, '
|
||||
$this->expectFailsRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleReqs(req2: 2)
|
||||
}
|
||||
}
|
||||
', [
|
||||
$this->missingFieldArg('multipleReqs', 'req1', 'Int!', 4, 13)
|
||||
]);
|
||||
',
|
||||
[$this->missingFieldArg('multipleReqs', 'req1', 'Int!', 4, 13)]
|
||||
);
|
||||
}
|
||||
|
||||
private function missingFieldArg($fieldName, $argName, $typeName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
ProvidedNonNullArguments::missingFieldArgMessage($fieldName, $argName, $typeName),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -189,46 +234,57 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMissingMultipleNonNullableArguments() : void
|
||||
{
|
||||
$this->expectFailsRule(new ProvidedNonNullArguments, '
|
||||
$this->expectFailsRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleReqs
|
||||
}
|
||||
}
|
||||
', [
|
||||
$this->missingFieldArg('multipleReqs', 'req1', 'Int!', 4, 13),
|
||||
$this->missingFieldArg('multipleReqs', 'req2', 'Int!', 4, 13),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->missingFieldArg('multipleReqs', 'req1', 'Int!', 4, 13),
|
||||
$this->missingFieldArg('multipleReqs', 'req2', 'Int!', 4, 13),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Describe: Directive arguments
|
||||
|
||||
/**
|
||||
* @see it('Incorrect value and missing argument')
|
||||
*/
|
||||
public function testIncorrectValueAndMissingArgument() : void
|
||||
{
|
||||
$this->expectFailsRule(new ProvidedNonNullArguments, '
|
||||
$this->expectFailsRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
complicatedArgs {
|
||||
multipleReqs(req1: "one")
|
||||
}
|
||||
}
|
||||
', [
|
||||
$this->missingFieldArg('multipleReqs', 'req2', 'Int!', 4, 13),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->missingFieldArg('multipleReqs', 'req2', 'Int!', 4, 13),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
// Describe: Directive arguments
|
||||
|
||||
/**
|
||||
* @see it('ignores unknown directives')
|
||||
*/
|
||||
public function testIgnoresUnknownDirectives() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
dog @unknown
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -236,7 +292,9 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testWithDirectivesOfValidTypes() : void
|
||||
{
|
||||
$this->expectPassesRule(new ProvidedNonNullArguments, '
|
||||
$this->expectPassesRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
dog @include(if: true) {
|
||||
name
|
||||
@ -245,7 +303,8 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
name
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -253,23 +312,19 @@ class ProvidedNonNullArgumentsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testWithDirectiveWithMissingTypes() : void
|
||||
{
|
||||
$this->expectFailsRule(new ProvidedNonNullArguments, '
|
||||
$this->expectFailsRule(
|
||||
new ProvidedNonNullArguments(),
|
||||
'
|
||||
{
|
||||
dog @include {
|
||||
name @skip
|
||||
}
|
||||
}
|
||||
', [
|
||||
$this->missingDirectiveArg('include', 'if', 'Boolean!', 3, 15),
|
||||
$this->missingDirectiveArg('skip', 'if', 'Boolean!', 4, 18)
|
||||
]);
|
||||
}
|
||||
|
||||
private function missingFieldArg($fieldName, $argName, $typeName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
ProvidedNonNullArguments::missingFieldArgMessage($fieldName, $argName, $typeName),
|
||||
[new SourceLocation($line, $column)]
|
||||
',
|
||||
[
|
||||
$this->missingDirectiveArg('include', 'if', 'Boolean!', 3, 15),
|
||||
$this->missingDirectiveArg('skip', 'if', 'Boolean!', 4, 18),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\Error;
|
||||
@ -8,39 +11,13 @@ use GraphQL\Validator\DocumentValidator;
|
||||
use GraphQL\Validator\Rules\CustomValidationRule;
|
||||
use GraphQL\Validator\Rules\QueryComplexity;
|
||||
use GraphQL\Validator\ValidationContext;
|
||||
use function count;
|
||||
|
||||
class QueryComplexityTest extends QuerySecurityTestCase
|
||||
{
|
||||
/** @var QueryComplexity */
|
||||
/** @var QueryComplexity */
|
||||
private static $rule;
|
||||
|
||||
/**
|
||||
* @param $max
|
||||
* @param $count
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getErrorMessage($max, $count)
|
||||
{
|
||||
return QueryComplexity::maxQueryComplexityErrorMessage($max, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $maxDepth
|
||||
*
|
||||
* @return QueryComplexity
|
||||
*/
|
||||
protected function getRule($maxDepth = null)
|
||||
{
|
||||
if (null === self::$rule) {
|
||||
self::$rule = new QueryComplexity($maxDepth);
|
||||
} elseif (null !== $maxDepth) {
|
||||
self::$rule->setMaxQueryComplexity($maxDepth);
|
||||
}
|
||||
|
||||
return self::$rule;
|
||||
}
|
||||
|
||||
public function testSimpleQueries() : void
|
||||
{
|
||||
$query = 'query MyQuery { human { firstName } }';
|
||||
@ -48,6 +25,19 @@ class QueryComplexityTest extends QuerySecurityTestCase
|
||||
$this->assertDocumentValidators($query, 2, 3);
|
||||
}
|
||||
|
||||
private function assertDocumentValidators($query, $queryComplexity, $startComplexity)
|
||||
{
|
||||
for ($maxComplexity = $startComplexity; $maxComplexity >= 0; --$maxComplexity) {
|
||||
$positions = [];
|
||||
|
||||
if ($maxComplexity < $queryComplexity && $maxComplexity !== QueryComplexity::DISABLED) {
|
||||
$positions = [$this->createFormattedError($maxComplexity, $queryComplexity)];
|
||||
}
|
||||
|
||||
$this->assertDocumentValidator($query, $maxComplexity, $positions);
|
||||
}
|
||||
}
|
||||
|
||||
public function testInlineFragmentQueries() : void
|
||||
{
|
||||
$query = 'query MyQuery { human { ... on Human { firstName } } }';
|
||||
@ -92,6 +82,22 @@ class QueryComplexityTest extends QuerySecurityTestCase
|
||||
$this->assertDocumentValidators($query, 3, 4);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $maxDepth
|
||||
*
|
||||
* @return QueryComplexity
|
||||
*/
|
||||
protected function getRule($maxDepth = null)
|
||||
{
|
||||
if (self::$rule === null) {
|
||||
self::$rule = new QueryComplexity($maxDepth);
|
||||
} elseif ($maxDepth !== null) {
|
||||
self::$rule->setMaxQueryComplexity($maxDepth);
|
||||
}
|
||||
|
||||
return self::$rule;
|
||||
}
|
||||
|
||||
public function testQueryWithEnabledIncludeDirectives() : void
|
||||
{
|
||||
$query = 'query MyQuery($withDogs: Boolean!) { human { dogs(name: "Root") @include(if:$withDogs) { name } } }';
|
||||
@ -133,8 +139,8 @@ class QueryComplexityTest extends QuerySecurityTestCase
|
||||
$query = 'query MyQuery($withDogs: Boolean!, $withoutDogName: Boolean!) { human { dogs(name: "Root") @include(if:$withDogs) { name @skip(if:$withoutDogName) } } }';
|
||||
|
||||
$this->getRule()->setRawVariableValues([
|
||||
'withDogs' => true,
|
||||
'withoutDogName' => true
|
||||
'withDogs' => true,
|
||||
'withoutDogName' => true,
|
||||
]);
|
||||
|
||||
$this->assertDocumentValidators($query, 2, 3);
|
||||
@ -159,16 +165,19 @@ class QueryComplexityTest extends QuerySecurityTestCase
|
||||
{
|
||||
$query = 'query MyQuery { human(name: INVALID_VALUE) { dogs {name} } }';
|
||||
|
||||
$reportedError = new Error("OtherValidatorError");
|
||||
$otherRule = new CustomValidationRule('otherRule', function(ValidationContext $context) use ($reportedError) {
|
||||
return [
|
||||
NodeKind::OPERATION_DEFINITION => [
|
||||
'leave' => function() use ($context, $reportedError) {
|
||||
$context->reportError($reportedError);
|
||||
}
|
||||
]
|
||||
];
|
||||
});
|
||||
$reportedError = new Error('OtherValidatorError');
|
||||
$otherRule = new CustomValidationRule(
|
||||
'otherRule',
|
||||
function (ValidationContext $context) use ($reportedError) {
|
||||
return [
|
||||
NodeKind::OPERATION_DEFINITION => [
|
||||
'leave' => function () use ($context, $reportedError) {
|
||||
$context->reportError($reportedError);
|
||||
},
|
||||
],
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
$errors = DocumentValidator::validate(
|
||||
QuerySecuritySchema::buildSchema(),
|
||||
@ -187,16 +196,14 @@ class QueryComplexityTest extends QuerySecurityTestCase
|
||||
);
|
||||
}
|
||||
|
||||
private function assertDocumentValidators($query, $queryComplexity, $startComplexity)
|
||||
/**
|
||||
* @param int $max
|
||||
* @param int $count
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getErrorMessage($max, $count)
|
||||
{
|
||||
for ($maxComplexity = $startComplexity; $maxComplexity >= 0; --$maxComplexity) {
|
||||
$positions = [];
|
||||
|
||||
if ($maxComplexity < $queryComplexity && $maxComplexity !== QueryComplexity::DISABLED) {
|
||||
$positions = [$this->createFormattedError($maxComplexity, $queryComplexity)];
|
||||
}
|
||||
|
||||
$this->assertDocumentValidator($query, $maxComplexity, $positions);
|
||||
}
|
||||
return QueryComplexity::maxQueryComplexityErrorMessage($max, $count);
|
||||
}
|
||||
}
|
||||
|
@ -1,35 +1,19 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Validator\Rules\QueryDepth;
|
||||
use function sprintf;
|
||||
use function str_replace;
|
||||
|
||||
class QueryDepthTest extends QuerySecurityTestCase
|
||||
{
|
||||
/**
|
||||
* @param $max
|
||||
* @param $count
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getErrorMessage($max, $count)
|
||||
{
|
||||
return QueryDepth::maxQueryDepthErrorMessage($max, $count);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $maxDepth
|
||||
*
|
||||
* @return QueryDepth
|
||||
*/
|
||||
protected function getRule($maxDepth)
|
||||
{
|
||||
return new QueryDepth($maxDepth);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $queryDepth
|
||||
* @param int $maxQueryDepth
|
||||
* @param array $expectedErrors
|
||||
* @param int $queryDepth
|
||||
* @param int $maxQueryDepth
|
||||
* @param string[][] $expectedErrors
|
||||
* @dataProvider queryDataProvider
|
||||
*/
|
||||
public function testSimpleQueries($queryDepth, $maxQueryDepth = 7, $expectedErrors = []) : void
|
||||
@ -37,26 +21,81 @@ class QueryDepthTest extends QuerySecurityTestCase
|
||||
$this->assertDocumentValidator($this->buildRecursiveQuery($queryDepth), $maxQueryDepth, $expectedErrors);
|
||||
}
|
||||
|
||||
private function buildRecursiveQuery($depth)
|
||||
{
|
||||
$query = sprintf('query MyQuery { human%s }', $this->buildRecursiveQueryPart($depth));
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function buildRecursiveQueryPart($depth)
|
||||
{
|
||||
$templates = [
|
||||
'human' => ' { firstName%s } ',
|
||||
'dog' => ' dogs { name%s } ',
|
||||
];
|
||||
|
||||
$part = $templates['human'];
|
||||
|
||||
for ($i = 1; $i <= $depth; ++$i) {
|
||||
$key = ($i % 2 === 1) ? 'human' : 'dog';
|
||||
$template = $templates[$key];
|
||||
|
||||
$part = sprintf($part, ($key === 'human' ? ' owner ' : '') . $template);
|
||||
}
|
||||
$part = str_replace('%s', '', $part);
|
||||
|
||||
return $part;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $queryDepth
|
||||
* @param int $maxQueryDepth
|
||||
* @param array $expectedErrors
|
||||
* @param int $queryDepth
|
||||
* @param int $maxQueryDepth
|
||||
* @param string[][] $expectedErrors
|
||||
* @dataProvider queryDataProvider
|
||||
*/
|
||||
public function testFragmentQueries($queryDepth, $maxQueryDepth = 7, $expectedErrors = []) : void
|
||||
{
|
||||
$this->assertDocumentValidator($this->buildRecursiveUsingFragmentQuery($queryDepth), $maxQueryDepth, $expectedErrors);
|
||||
$this->assertDocumentValidator(
|
||||
$this->buildRecursiveUsingFragmentQuery($queryDepth),
|
||||
$maxQueryDepth,
|
||||
$expectedErrors
|
||||
);
|
||||
}
|
||||
|
||||
private function buildRecursiveUsingFragmentQuery($depth)
|
||||
{
|
||||
$query = sprintf(
|
||||
'query MyQuery { human { ...F1 } } fragment F1 on Human %s',
|
||||
$this->buildRecursiveQueryPart($depth)
|
||||
);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $queryDepth
|
||||
* @param int $maxQueryDepth
|
||||
* @param array $expectedErrors
|
||||
* @param int $queryDepth
|
||||
* @param int $maxQueryDepth
|
||||
* @param string[][] $expectedErrors
|
||||
* @dataProvider queryDataProvider
|
||||
*/
|
||||
public function testInlineFragmentQueries($queryDepth, $maxQueryDepth = 7, $expectedErrors = []) : void
|
||||
{
|
||||
$this->assertDocumentValidator($this->buildRecursiveUsingInlineFragmentQuery($queryDepth), $maxQueryDepth, $expectedErrors);
|
||||
$this->assertDocumentValidator(
|
||||
$this->buildRecursiveUsingInlineFragmentQuery($queryDepth),
|
||||
$maxQueryDepth,
|
||||
$expectedErrors
|
||||
);
|
||||
}
|
||||
|
||||
private function buildRecursiveUsingInlineFragmentQuery($depth)
|
||||
{
|
||||
$query = sprintf(
|
||||
'query MyQuery { human { ...on Human %s } }',
|
||||
$this->buildRecursiveQueryPart($depth)
|
||||
);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
public function testComplexityIntrospectionQuery() : void
|
||||
@ -99,50 +138,24 @@ class QueryDepthTest extends QuerySecurityTestCase
|
||||
];
|
||||
}
|
||||
|
||||
private function buildRecursiveQuery($depth)
|
||||
/**
|
||||
* @param int $max
|
||||
* @param int $count
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function getErrorMessage($max, $count)
|
||||
{
|
||||
$query = sprintf('query MyQuery { human%s }', $this->buildRecursiveQueryPart($depth));
|
||||
|
||||
return $query;
|
||||
return QueryDepth::maxQueryDepthErrorMessage($max, $count);
|
||||
}
|
||||
|
||||
private function buildRecursiveUsingFragmentQuery($depth)
|
||||
/**
|
||||
* @param int $maxDepth
|
||||
*
|
||||
* @return QueryDepth
|
||||
*/
|
||||
protected function getRule($maxDepth)
|
||||
{
|
||||
$query = sprintf(
|
||||
'query MyQuery { human { ...F1 } } fragment F1 on Human %s',
|
||||
$this->buildRecursiveQueryPart($depth)
|
||||
);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function buildRecursiveUsingInlineFragmentQuery($depth)
|
||||
{
|
||||
$query = sprintf(
|
||||
'query MyQuery { human { ...on Human %s } }',
|
||||
$this->buildRecursiveQueryPart($depth)
|
||||
);
|
||||
|
||||
return $query;
|
||||
}
|
||||
|
||||
private function buildRecursiveQueryPart($depth)
|
||||
{
|
||||
$templates = [
|
||||
'human' => ' { firstName%s } ',
|
||||
'dog' => ' dogs { name%s } ',
|
||||
];
|
||||
|
||||
$part = $templates['human'];
|
||||
|
||||
for ($i = 1; $i <= $depth; ++$i) {
|
||||
$key = ($i % 2 == 1) ? 'human' : 'dog';
|
||||
$template = $templates[$key];
|
||||
|
||||
$part = sprintf($part, ('human' == $key ? ' owner ' : '').$template);
|
||||
}
|
||||
$part = str_replace('%s', '', $part);
|
||||
|
||||
return $part;
|
||||
return new QueryDepth($maxDepth);
|
||||
}
|
||||
}
|
||||
|
@ -1,18 +1,25 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Type\Schema;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Schema;
|
||||
|
||||
class QuerySecuritySchema
|
||||
{
|
||||
/** @var Schema */
|
||||
private static $schema;
|
||||
|
||||
/** @var ObjectType */
|
||||
private static $dogType;
|
||||
|
||||
/** @var ObjectType */
|
||||
private static $humanType;
|
||||
|
||||
/** @var ObjectType */
|
||||
private static $queryRootType;
|
||||
|
||||
/**
|
||||
@ -20,12 +27,12 @@ class QuerySecuritySchema
|
||||
*/
|
||||
public static function buildSchema()
|
||||
{
|
||||
if (null !== self::$schema) {
|
||||
if (self::$schema !== null) {
|
||||
return self::$schema;
|
||||
}
|
||||
|
||||
self::$schema = new Schema([
|
||||
'query' => static::buildQueryRootType()
|
||||
'query' => static::buildQueryRootType(),
|
||||
]);
|
||||
|
||||
return self::$schema;
|
||||
@ -33,12 +40,12 @@ class QuerySecuritySchema
|
||||
|
||||
public static function buildQueryRootType()
|
||||
{
|
||||
if (null !== self::$queryRootType) {
|
||||
if (self::$queryRootType !== null) {
|
||||
return self::$queryRootType;
|
||||
}
|
||||
|
||||
self::$queryRootType = new ObjectType([
|
||||
'name' => 'QueryRoot',
|
||||
'name' => 'QueryRoot',
|
||||
'fields' => [
|
||||
'human' => [
|
||||
'type' => self::buildHumanType(),
|
||||
@ -52,18 +59,18 @@ class QuerySecuritySchema
|
||||
|
||||
public static function buildHumanType()
|
||||
{
|
||||
if (null !== self::$humanType) {
|
||||
if (self::$humanType !== null) {
|
||||
return self::$humanType;
|
||||
}
|
||||
|
||||
self::$humanType = new ObjectType(
|
||||
[
|
||||
'name' => 'Human',
|
||||
'fields' => function() {
|
||||
'name' => 'Human',
|
||||
'fields' => function () {
|
||||
return [
|
||||
'firstName' => ['type' => Type::nonNull(Type::string())],
|
||||
'dogs' => [
|
||||
'type' => Type::nonNull(
|
||||
'dogs' => [
|
||||
'type' => Type::nonNull(
|
||||
Type::listOf(
|
||||
Type::nonNull(self::buildDogType())
|
||||
)
|
||||
@ -73,7 +80,7 @@ class QuerySecuritySchema
|
||||
|
||||
return $childrenComplexity + $complexity;
|
||||
},
|
||||
'args' => ['name' => ['type' => Type::string()]],
|
||||
'args' => ['name' => ['type' => Type::string()]],
|
||||
],
|
||||
];
|
||||
},
|
||||
@ -85,15 +92,15 @@ class QuerySecuritySchema
|
||||
|
||||
public static function buildDogType()
|
||||
{
|
||||
if (null !== self::$dogType) {
|
||||
if (self::$dogType !== null) {
|
||||
return self::$dogType;
|
||||
}
|
||||
|
||||
self::$dogType = new ObjectType(
|
||||
[
|
||||
'name' => 'Dog',
|
||||
'name' => 'Dog',
|
||||
'fields' => [
|
||||
'name' => ['type' => Type::nonNull(Type::string())],
|
||||
'name' => ['type' => Type::nonNull(Type::string())],
|
||||
'master' => [
|
||||
'type' => self::buildHumanType(),
|
||||
],
|
||||
|
@ -1,30 +1,20 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\Error;
|
||||
use GraphQL\Error\FormattedError;
|
||||
use GraphQL\Language\Parser;
|
||||
use GraphQL\Type\Introspection;
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
use GraphQL\Validator\Rules\QuerySecurityRule;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function array_map;
|
||||
|
||||
abstract class QuerySecurityTestCase extends TestCase
|
||||
{
|
||||
/**
|
||||
* @param $max
|
||||
*
|
||||
* @return QuerySecurityRule
|
||||
*/
|
||||
abstract protected function getRule($max);
|
||||
|
||||
/**
|
||||
* @param $max
|
||||
* @param $count
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getErrorMessage($max, $count);
|
||||
|
||||
/**
|
||||
* @expectedException \InvalidArgumentException
|
||||
* @expectedExceptionMessage argument must be greater or equal to 0.
|
||||
@ -34,23 +24,12 @@ abstract class QuerySecurityTestCase extends TestCase
|
||||
$this->getRule(-1);
|
||||
}
|
||||
|
||||
protected function createFormattedError($max, $count, $locations = [])
|
||||
{
|
||||
return FormattedError::create($this->getErrorMessage($max, $count), $locations);
|
||||
}
|
||||
|
||||
protected function assertDocumentValidator($queryString, $max, array $expectedErrors = [])
|
||||
{
|
||||
$errors = DocumentValidator::validate(
|
||||
QuerySecuritySchema::buildSchema(),
|
||||
Parser::parse($queryString),
|
||||
[$this->getRule($max)]
|
||||
);
|
||||
|
||||
$this->assertEquals($expectedErrors, array_map(['GraphQL\Error\Error', 'formatError'], $errors), $queryString);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
/**
|
||||
* @param int $max
|
||||
*
|
||||
* @return QuerySecurityRule
|
||||
*/
|
||||
abstract protected function getRule($max);
|
||||
|
||||
protected function assertIntrospectionQuery($maxExpected)
|
||||
{
|
||||
@ -59,6 +38,48 @@ abstract class QuerySecurityTestCase extends TestCase
|
||||
$this->assertMaxValue($query, $maxExpected);
|
||||
}
|
||||
|
||||
protected function assertMaxValue($query, $maxExpected)
|
||||
{
|
||||
$this->assertDocumentValidator($query, $maxExpected);
|
||||
$newMax = $maxExpected - 1;
|
||||
if ($newMax === QuerySecurityRule::DISABLED) {
|
||||
return;
|
||||
}
|
||||
$this->assertDocumentValidator($query, $newMax, [$this->createFormattedError($newMax, $maxExpected)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $queryString
|
||||
* @param int $max
|
||||
* @param string[][] $expectedErrors
|
||||
* @return Error[]
|
||||
*/
|
||||
protected function assertDocumentValidator($queryString, $max, array $expectedErrors = []) : array
|
||||
{
|
||||
$errors = DocumentValidator::validate(
|
||||
QuerySecuritySchema::buildSchema(),
|
||||
Parser::parse($queryString),
|
||||
[$this->getRule($max)]
|
||||
);
|
||||
|
||||
$this->assertEquals($expectedErrors, array_map([Error::class, 'formatError'], $errors), $queryString);
|
||||
|
||||
return $errors;
|
||||
}
|
||||
|
||||
protected function createFormattedError($max, $count, $locations = [])
|
||||
{
|
||||
return FormattedError::create($this->getErrorMessage($max, $count), $locations);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $max
|
||||
* @param int $count
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
abstract protected function getErrorMessage($max, $count);
|
||||
|
||||
protected function assertIntrospectionTypeMetaFieldQuery($maxExpected)
|
||||
{
|
||||
$query = '
|
||||
@ -84,14 +105,4 @@ abstract class QuerySecurityTestCase extends TestCase
|
||||
';
|
||||
$this->assertMaxValue($query, $maxExpected);
|
||||
}
|
||||
|
||||
protected function assertMaxValue($query, $maxExpected)
|
||||
{
|
||||
$this->assertDocumentValidator($query, $maxExpected);
|
||||
$newMax = $maxExpected - 1;
|
||||
if ($newMax === QuerySecurityRule::DISABLED) {
|
||||
return;
|
||||
}
|
||||
$this->assertDocumentValidator($query, $newMax, [$this->createFormattedError($newMax, $maxExpected)]);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\ScalarLeafs;
|
||||
class ScalarLeafsTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Scalar leafs
|
||||
|
||||
/**
|
||||
* @see it('valid scalar selection')
|
||||
*/
|
||||
public function testValidScalarSelection() : void
|
||||
{
|
||||
$this->expectPassesRule(new ScalarLeafs, '
|
||||
$this->expectPassesRule(
|
||||
new ScalarLeafs(),
|
||||
'
|
||||
fragment scalarSelection on Dog {
|
||||
barks
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,11 +31,23 @@ class ScalarLeafsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testObjectTypeMissingSelection() : void
|
||||
{
|
||||
$this->expectFailsRule(new ScalarLeafs, '
|
||||
$this->expectFailsRule(
|
||||
new ScalarLeafs(),
|
||||
'
|
||||
query directQueryOnObjectWithoutSubFields {
|
||||
human
|
||||
}
|
||||
', [$this->missingObjSubselection('human', 'Human', 3, 9)]);
|
||||
',
|
||||
[$this->missingObjSubselection('human', 'Human', 3, 9)]
|
||||
);
|
||||
}
|
||||
|
||||
private function missingObjSubselection($field, $type, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
ScalarLeafs::requiredSubselectionMessage($field, $type),
|
||||
[new SourceLocation($line, $column)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,11 +55,15 @@ class ScalarLeafsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInterfaceTypeMissingSelection() : void
|
||||
{
|
||||
$this->expectFailsRule(new ScalarLeafs, '
|
||||
$this->expectFailsRule(
|
||||
new ScalarLeafs(),
|
||||
'
|
||||
{
|
||||
human { pets }
|
||||
}
|
||||
', [$this->missingObjSubselection('pets', '[Pet]', 3, 17)]);
|
||||
',
|
||||
[$this->missingObjSubselection('pets', '[Pet]', 3, 17)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,11 +71,14 @@ class ScalarLeafsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testValidScalarSelectionWithArgs() : void
|
||||
{
|
||||
$this->expectPassesRule(new ScalarLeafs, '
|
||||
$this->expectPassesRule(
|
||||
new ScalarLeafs(),
|
||||
'
|
||||
fragment scalarSelectionWithArgs on Dog {
|
||||
doesKnowCommand(dogCommand: SIT)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,67 +86,14 @@ class ScalarLeafsTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testScalarSelectionNotAllowedOnBoolean() : void
|
||||
{
|
||||
$this->expectFailsRule(new ScalarLeafs, '
|
||||
$this->expectFailsRule(
|
||||
new ScalarLeafs(),
|
||||
'
|
||||
fragment scalarSelectionsNotAllowedOnBoolean on Dog {
|
||||
barks { sinceWhen }
|
||||
}
|
||||
',
|
||||
[$this->noScalarSubselection('barks', 'Boolean', 3, 15)]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('scalar selection not allowed on Enum')
|
||||
*/
|
||||
public function testScalarSelectionNotAllowedOnEnum() : void
|
||||
{
|
||||
$this->expectFailsRule(new ScalarLeafs, '
|
||||
fragment scalarSelectionsNotAllowedOnEnum on Cat {
|
||||
furColor { inHexdec }
|
||||
}
|
||||
',
|
||||
[$this->noScalarSubselection('furColor', 'FurColor', 3, 18)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('scalar selection not allowed with args')
|
||||
*/
|
||||
public function testScalarSelectionNotAllowedWithArgs() : void
|
||||
{
|
||||
$this->expectFailsRule(new ScalarLeafs, '
|
||||
fragment scalarSelectionsNotAllowedWithArgs on Dog {
|
||||
doesKnowCommand(dogCommand: SIT) { sinceWhen }
|
||||
}
|
||||
',
|
||||
[$this->noScalarSubselection('doesKnowCommand', 'Boolean', 3, 42)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('Scalar selection not allowed with directives')
|
||||
*/
|
||||
public function testScalarSelectionNotAllowedWithDirectives() : void
|
||||
{
|
||||
$this->expectFailsRule(new ScalarLeafs, '
|
||||
fragment scalarSelectionsNotAllowedWithDirectives on Dog {
|
||||
name @include(if: true) { isAlsoHumanName }
|
||||
}
|
||||
',
|
||||
[$this->noScalarSubselection('name', 'String', 3, 33)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('Scalar selection not allowed with directives and args')
|
||||
*/
|
||||
public function testScalarSelectionNotAllowedWithDirectivesAndArgs() : void
|
||||
{
|
||||
$this->expectFailsRule(new ScalarLeafs, '
|
||||
fragment scalarSelectionsNotAllowedWithDirectivesAndArgs on Dog {
|
||||
doesKnowCommand(dogCommand: SIT) @include(if: true) { sinceWhen }
|
||||
}
|
||||
',
|
||||
[$this->noScalarSubselection('doesKnowCommand', 'Boolean', 3, 61)]
|
||||
[$this->noScalarSubselection('barks', 'Boolean', 3, 15)]
|
||||
);
|
||||
}
|
||||
|
||||
@ -134,11 +105,67 @@ class ScalarLeafsTest extends ValidatorTestCase
|
||||
);
|
||||
}
|
||||
|
||||
private function missingObjSubselection($field, $type, $line, $column)
|
||||
/**
|
||||
* @see it('scalar selection not allowed on Enum')
|
||||
*/
|
||||
public function testScalarSelectionNotAllowedOnEnum() : void
|
||||
{
|
||||
return FormattedError::create(
|
||||
ScalarLeafs::requiredSubselectionMessage($field, $type),
|
||||
[new SourceLocation($line, $column)]
|
||||
$this->expectFailsRule(
|
||||
new ScalarLeafs(),
|
||||
'
|
||||
fragment scalarSelectionsNotAllowedOnEnum on Cat {
|
||||
furColor { inHexdec }
|
||||
}
|
||||
',
|
||||
[$this->noScalarSubselection('furColor', 'FurColor', 3, 18)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('scalar selection not allowed with args')
|
||||
*/
|
||||
public function testScalarSelectionNotAllowedWithArgs() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new ScalarLeafs(),
|
||||
'
|
||||
fragment scalarSelectionsNotAllowedWithArgs on Dog {
|
||||
doesKnowCommand(dogCommand: SIT) { sinceWhen }
|
||||
}
|
||||
',
|
||||
[$this->noScalarSubselection('doesKnowCommand', 'Boolean', 3, 42)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('Scalar selection not allowed with directives')
|
||||
*/
|
||||
public function testScalarSelectionNotAllowedWithDirectives() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new ScalarLeafs(),
|
||||
'
|
||||
fragment scalarSelectionsNotAllowedWithDirectives on Dog {
|
||||
name @include(if: true) { isAlsoHumanName }
|
||||
}
|
||||
',
|
||||
[$this->noScalarSubselection('name', 'String', 3, 33)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('Scalar selection not allowed with directives and args')
|
||||
*/
|
||||
public function testScalarSelectionNotAllowedWithDirectivesAndArgs() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new ScalarLeafs(),
|
||||
'
|
||||
fragment scalarSelectionsNotAllowedWithDirectivesAndArgs on Dog {
|
||||
doesKnowCommand(dogCommand: SIT) @include(if: true) { sinceWhen }
|
||||
}
|
||||
',
|
||||
[$this->noScalarSubselection('doesKnowCommand', 'Boolean', 3, 61)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\UniqueArgumentNames;
|
||||
class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Unique argument names
|
||||
|
||||
/**
|
||||
* @see it('no arguments on field')
|
||||
*/
|
||||
public function testNoArgumentsOnField() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueArgumentNames(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,11 +31,14 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoArgumentsOnDirective() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field @directive
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,11 +46,14 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testArgumentOnField() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field(arg: "value")
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,11 +61,14 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testArgumentOnDirective() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field @directive(arg: "value")
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,12 +76,15 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSameArgumentOnTwoFields() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
one: field(arg: "value")
|
||||
two: field(arg: "value")
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -75,11 +92,14 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSameArgumentOnFieldAndDirective() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field(arg: "value") @directive(arg: "value")
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -87,11 +107,14 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSameArgumentOnTwoDirectives() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field @directive1(arg: "value") @directive2(arg: "value")
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,11 +122,14 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleFieldArguments() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field(arg1: "value", arg2: "value", arg3: "value")
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -111,11 +137,14 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleDirectiveArguments() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueArgumentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field @directive(arg1: "value", arg2: "value", arg3: "value")
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -123,57 +152,15 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDuplicateFieldArguments() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueArgumentNames, '
|
||||
$this->expectFailsRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field(arg1: "value", arg1: "value")
|
||||
}
|
||||
', [
|
||||
$this->duplicateArg('arg1', 3, 15, 3, 30)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('many duplicate field arguments')
|
||||
*/
|
||||
public function testManyDuplicateFieldArguments() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueArgumentNames, '
|
||||
{
|
||||
field(arg1: "value", arg1: "value", arg1: "value")
|
||||
}
|
||||
', [
|
||||
$this->duplicateArg('arg1', 3, 15, 3, 30),
|
||||
$this->duplicateArg('arg1', 3, 15, 3, 45)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('duplicate directive arguments')
|
||||
*/
|
||||
public function testDuplicateDirectiveArguments() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueArgumentNames, '
|
||||
{
|
||||
field @directive(arg1: "value", arg1: "value")
|
||||
}
|
||||
', [
|
||||
$this->duplicateArg('arg1', 3, 26, 3, 41)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('many duplicate directive arguments')
|
||||
*/
|
||||
public function testManyDuplicateDirectiveArguments() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueArgumentNames, '
|
||||
{
|
||||
field @directive(arg1: "value", arg1: "value", arg1: "value")
|
||||
}
|
||||
', [
|
||||
$this->duplicateArg('arg1', 3, 26, 3, 41),
|
||||
$this->duplicateArg('arg1', 3, 26, 3, 56)
|
||||
]);
|
||||
',
|
||||
[$this->duplicateArg('arg1', 3, 15, 3, 30)]
|
||||
);
|
||||
}
|
||||
|
||||
private function duplicateArg($argName, $l1, $c1, $l2, $c2)
|
||||
@ -183,4 +170,58 @@ class UniqueArgumentNamesTest extends ValidatorTestCase
|
||||
[new SourceLocation($l1, $c1), new SourceLocation($l2, $c2)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('many duplicate field arguments')
|
||||
*/
|
||||
public function testManyDuplicateFieldArguments() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field(arg1: "value", arg1: "value", arg1: "value")
|
||||
}
|
||||
',
|
||||
[
|
||||
$this->duplicateArg('arg1', 3, 15, 3, 30),
|
||||
$this->duplicateArg('arg1', 3, 15, 3, 45),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('duplicate directive arguments')
|
||||
*/
|
||||
public function testDuplicateDirectiveArguments() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field @directive(arg1: "value", arg1: "value")
|
||||
}
|
||||
',
|
||||
[$this->duplicateArg('arg1', 3, 26, 3, 41)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('many duplicate directive arguments')
|
||||
*/
|
||||
public function testManyDuplicateDirectiveArguments() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new UniqueArgumentNames(),
|
||||
'
|
||||
{
|
||||
field @directive(arg1: "value", arg1: "value", arg1: "value")
|
||||
}
|
||||
',
|
||||
[
|
||||
$this->duplicateArg('arg1', 3, 26, 3, 41),
|
||||
$this->duplicateArg('arg1', 3, 26, 3, 56),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Validator\Rules\UniqueDirectivesPerLocation;
|
||||
@ -10,11 +13,14 @@ class UniqueDirectivesPerLocationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testNoDirectives() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueDirectivesPerLocation(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueDirectivesPerLocation(),
|
||||
'
|
||||
fragment Test on Type {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -22,11 +28,14 @@ class UniqueDirectivesPerLocationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUniqueDirectivesInDifferentLocations() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueDirectivesPerLocation(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueDirectivesPerLocation(),
|
||||
'
|
||||
fragment Test on Type @directiveA {
|
||||
field @directiveB
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -34,11 +43,14 @@ class UniqueDirectivesPerLocationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testUniqueDirectivesInSameLocations() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueDirectivesPerLocation(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueDirectivesPerLocation(),
|
||||
'
|
||||
fragment Test on Type @directiveA @directiveB {
|
||||
field @directiveA @directiveB
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -46,11 +58,14 @@ class UniqueDirectivesPerLocationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSameDirectivesInDifferentLocations() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueDirectivesPerLocation(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueDirectivesPerLocation(),
|
||||
'
|
||||
fragment Test on Type @directiveA {
|
||||
field @directiveA
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,12 +73,15 @@ class UniqueDirectivesPerLocationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSameDirectivesInSimilarLocations() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueDirectivesPerLocation(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueDirectivesPerLocation(),
|
||||
'
|
||||
fragment Test on Type {
|
||||
field @directive
|
||||
field @directive
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,13 +89,26 @@ class UniqueDirectivesPerLocationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDuplicateDirectivesInOneLocation() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueDirectivesPerLocation(), '
|
||||
$this->expectFailsRule(
|
||||
new UniqueDirectivesPerLocation(),
|
||||
'
|
||||
fragment Test on Type {
|
||||
field @directive @directive
|
||||
}
|
||||
', [
|
||||
$this->duplicateDirective('directive', 3, 15, 3, 26)
|
||||
]);
|
||||
',
|
||||
[$this->duplicateDirective('directive', 3, 15, 3, 26)]
|
||||
);
|
||||
}
|
||||
|
||||
private function duplicateDirective($directiveName, $l1, $c1, $l2, $c2)
|
||||
{
|
||||
return [
|
||||
'message' => UniqueDirectivesPerLocation::duplicateDirectiveMessage($directiveName),
|
||||
'locations' => [
|
||||
['line' => $l1, 'column' => $c1],
|
||||
['line' => $l2, 'column' => $c2],
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
@ -85,14 +116,18 @@ class UniqueDirectivesPerLocationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testManyDuplicateDirectivesInOneLocation() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueDirectivesPerLocation(), '
|
||||
$this->expectFailsRule(
|
||||
new UniqueDirectivesPerLocation(),
|
||||
'
|
||||
fragment Test on Type {
|
||||
field @directive @directive @directive
|
||||
}
|
||||
', [
|
||||
$this->duplicateDirective('directive', 3, 15, 3, 26),
|
||||
$this->duplicateDirective('directive', 3, 15, 3, 37)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->duplicateDirective('directive', 3, 15, 3, 26),
|
||||
$this->duplicateDirective('directive', 3, 15, 3, 37),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,14 +135,18 @@ class UniqueDirectivesPerLocationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDifferentDuplicateDirectivesInOneLocation() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueDirectivesPerLocation, '
|
||||
$this->expectFailsRule(
|
||||
new UniqueDirectivesPerLocation(),
|
||||
'
|
||||
fragment Test on Type {
|
||||
field @directiveA @directiveB @directiveA @directiveB
|
||||
}
|
||||
', [
|
||||
$this->duplicateDirective('directiveA', 3, 15, 3, 39),
|
||||
$this->duplicateDirective('directiveB', 3, 27, 3, 51)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->duplicateDirective('directiveA', 3, 15, 3, 39),
|
||||
$this->duplicateDirective('directiveB', 3, 27, 3, 51),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -115,24 +154,17 @@ class UniqueDirectivesPerLocationTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDuplicateDirectivesInManyLocations() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueDirectivesPerLocation(), '
|
||||
$this->expectFailsRule(
|
||||
new UniqueDirectivesPerLocation(),
|
||||
'
|
||||
fragment Test on Type @directive @directive {
|
||||
field @directive @directive
|
||||
}
|
||||
', [
|
||||
$this->duplicateDirective('directive', 2, 29, 2, 40),
|
||||
$this->duplicateDirective('directive', 3, 15, 3, 26)
|
||||
]);
|
||||
}
|
||||
|
||||
private function duplicateDirective($directiveName, $l1, $c1, $l2, $c2)
|
||||
{
|
||||
return [
|
||||
'message' =>UniqueDirectivesPerLocation::duplicateDirectiveMessage($directiveName),
|
||||
'locations' => [
|
||||
['line' => $l1, 'column' => $c1],
|
||||
['line' => $l2, 'column' => $c2]
|
||||
',
|
||||
[
|
||||
$this->duplicateDirective('directive', 2, 29, 2, 40),
|
||||
$this->duplicateDirective('directive', 3, 15, 3, 26),
|
||||
]
|
||||
];
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\UniqueFragmentNames;
|
||||
class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Unique fragment names
|
||||
|
||||
/**
|
||||
* @see it('no fragments')
|
||||
*/
|
||||
public function testNoFragments() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueFragmentNames(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueFragmentNames(),
|
||||
'
|
||||
{
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,7 +31,9 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testOneFragment() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueFragmentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueFragmentNames(),
|
||||
'
|
||||
{
|
||||
...fragA
|
||||
}
|
||||
@ -34,7 +41,8 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
fragment fragA on Type {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -42,7 +50,9 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testManyFragments() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueFragmentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueFragmentNames(),
|
||||
'
|
||||
{
|
||||
...fragA
|
||||
...fragB
|
||||
@ -57,7 +67,8 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
fragment fragC on Type {
|
||||
fieldC
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,7 +76,9 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testInlineFragmentsAreAlwaysUnique() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueFragmentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueFragmentNames(),
|
||||
'
|
||||
{
|
||||
...on Type {
|
||||
fieldA
|
||||
@ -74,7 +87,8 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
fieldB
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -82,14 +96,17 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testFragmentAndOperationNamedTheSame() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueFragmentNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueFragmentNames(),
|
||||
'
|
||||
query Foo {
|
||||
...Foo
|
||||
}
|
||||
fragment Foo on Type {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -97,7 +114,9 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testFragmentsNamedTheSame() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueFragmentNames, '
|
||||
$this->expectFailsRule(
|
||||
new UniqueFragmentNames(),
|
||||
'
|
||||
{
|
||||
...fragA
|
||||
}
|
||||
@ -107,26 +126,9 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
fragment fragA on Type {
|
||||
fieldB
|
||||
}
|
||||
', [
|
||||
$this->duplicateFrag('fragA', 5, 16, 8, 16)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('fragments named the same without being referenced')
|
||||
*/
|
||||
public function testFragmentsNamedTheSameWithoutBeingReferenced() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueFragmentNames, '
|
||||
fragment fragA on Type {
|
||||
fieldA
|
||||
}
|
||||
fragment fragA on Type {
|
||||
fieldB
|
||||
}
|
||||
', [
|
||||
$this->duplicateFrag('fragA', 2, 16, 5, 16)
|
||||
]);
|
||||
',
|
||||
[$this->duplicateFrag('fragA', 5, 16, 8, 16)]
|
||||
);
|
||||
}
|
||||
|
||||
private function duplicateFrag($fragName, $l1, $c1, $l2, $c2)
|
||||
@ -136,4 +138,23 @@ class UniqueFragmentNamesTest extends ValidatorTestCase
|
||||
[new SourceLocation($l1, $c1), new SourceLocation($l2, $c2)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('fragments named the same without being referenced')
|
||||
*/
|
||||
public function testFragmentsNamedTheSameWithoutBeingReferenced() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new UniqueFragmentNames(),
|
||||
'
|
||||
fragment fragA on Type {
|
||||
fieldA
|
||||
}
|
||||
fragment fragA on Type {
|
||||
fieldB
|
||||
}
|
||||
',
|
||||
[$this->duplicateFrag('fragA', 2, 16, 5, 16)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\UniqueInputFieldNames;
|
||||
class UniqueInputFieldNamesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Unique input field names
|
||||
|
||||
/**
|
||||
* @see it('input object with fields')
|
||||
*/
|
||||
public function testInputObjectWithFields() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueInputFieldNames(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueInputFieldNames(),
|
||||
'
|
||||
{
|
||||
field(arg: { f: true })
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,11 +31,14 @@ class UniqueInputFieldNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testSameInputObjectWithinTwoArgs() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueInputFieldNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueInputFieldNames(),
|
||||
'
|
||||
{
|
||||
field(arg1: { f: true }, arg2: { f: true })
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,11 +46,14 @@ class UniqueInputFieldNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleInputObjectFields() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueInputFieldNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueInputFieldNames(),
|
||||
'
|
||||
{
|
||||
field(arg: { f1: "value", f2: "value", f3: "value" })
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,7 +61,9 @@ class UniqueInputFieldNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testAllowsForNestedInputObjectsWithSimilarFields() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueInputFieldNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueInputFieldNames(),
|
||||
'
|
||||
{
|
||||
field(arg: {
|
||||
deep: {
|
||||
@ -62,7 +75,8 @@ class UniqueInputFieldNamesTest extends ValidatorTestCase
|
||||
id: 1
|
||||
})
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -70,28 +84,15 @@ class UniqueInputFieldNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDuplicateInputObjectFields() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueInputFieldNames, '
|
||||
$this->expectFailsRule(
|
||||
new UniqueInputFieldNames(),
|
||||
'
|
||||
{
|
||||
field(arg: { f1: "value", f1: "value" })
|
||||
}
|
||||
', [
|
||||
$this->duplicateField('f1', 3, 22, 3, 35)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('many duplicate input object fields')
|
||||
*/
|
||||
public function testManyDuplicateInputObjectFields() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueInputFieldNames, '
|
||||
{
|
||||
field(arg: { f1: "value", f1: "value", f1: "value" })
|
||||
}
|
||||
', [
|
||||
$this->duplicateField('f1', 3, 22, 3, 35),
|
||||
$this->duplicateField('f1', 3, 22, 3, 48)
|
||||
]);
|
||||
',
|
||||
[$this->duplicateField('f1', 3, 22, 3, 35)]
|
||||
);
|
||||
}
|
||||
|
||||
private function duplicateField($name, $l1, $c1, $l2, $c2)
|
||||
@ -101,4 +102,23 @@ class UniqueInputFieldNamesTest extends ValidatorTestCase
|
||||
[new SourceLocation($l1, $c1), new SourceLocation($l2, $c2)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('many duplicate input object fields')
|
||||
*/
|
||||
public function testManyDuplicateInputObjectFields() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new UniqueInputFieldNames(),
|
||||
'
|
||||
{
|
||||
field(arg: { f1: "value", f1: "value", f1: "value" })
|
||||
}
|
||||
',
|
||||
[
|
||||
$this->duplicateField('f1', 3, 22, 3, 35),
|
||||
$this->duplicateField('f1', 3, 22, 3, 48),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\UniqueOperationNames;
|
||||
class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Unique operation names
|
||||
|
||||
/**
|
||||
* @see it('no operations')
|
||||
*/
|
||||
public function testNoOperations() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueOperationNames(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueOperationNames(),
|
||||
'
|
||||
fragment fragA on Type {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,11 +31,14 @@ class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testOneAnonOperation() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueOperationNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueOperationNames(),
|
||||
'
|
||||
{
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -38,11 +46,14 @@ class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testOneNamedOperation() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueOperationNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueOperationNames(),
|
||||
'
|
||||
query Foo {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -50,7 +61,9 @@ class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleOperations() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueOperationNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueOperationNames(),
|
||||
'
|
||||
query Foo {
|
||||
field
|
||||
}
|
||||
@ -58,7 +71,8 @@ class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
query Bar {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -66,7 +80,9 @@ class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleOperationsOfDifferentTypes() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueOperationNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueOperationNames(),
|
||||
'
|
||||
query Foo {
|
||||
field
|
||||
}
|
||||
@ -78,7 +94,8 @@ class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
subscription Baz {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -86,14 +103,17 @@ class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testFragmentAndOperationNamedTheSame() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueOperationNames, '
|
||||
$this->expectPassesRule(
|
||||
new UniqueOperationNames(),
|
||||
'
|
||||
query Foo {
|
||||
...Foo
|
||||
}
|
||||
fragment Foo on Type {
|
||||
field
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -101,50 +121,18 @@ class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testMultipleOperationsOfSameName() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueOperationNames, '
|
||||
$this->expectFailsRule(
|
||||
new UniqueOperationNames(),
|
||||
'
|
||||
query Foo {
|
||||
fieldA
|
||||
}
|
||||
query Foo {
|
||||
fieldB
|
||||
}
|
||||
', [
|
||||
$this->duplicateOp('Foo', 2, 13, 5, 13)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('multiple ops of same name of different types (mutation)')
|
||||
*/
|
||||
public function testMultipleOpsOfSameNameOfDifferentTypesMutation() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueOperationNames, '
|
||||
query Foo {
|
||||
fieldA
|
||||
}
|
||||
mutation Foo {
|
||||
fieldB
|
||||
}
|
||||
', [
|
||||
$this->duplicateOp('Foo', 2, 13, 5, 16)
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('multiple ops of same name of different types (subscription)')
|
||||
*/
|
||||
public function testMultipleOpsOfSameNameOfDifferentTypesSubscription() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueOperationNames, '
|
||||
query Foo {
|
||||
fieldA
|
||||
}
|
||||
subscription Foo {
|
||||
fieldB
|
||||
}
|
||||
', [
|
||||
$this->duplicateOp('Foo', 2, 13, 5, 20)
|
||||
]);
|
||||
',
|
||||
[$this->duplicateOp('Foo', 2, 13, 5, 13)]
|
||||
);
|
||||
}
|
||||
|
||||
private function duplicateOp($opName, $l1, $c1, $l2, $c2)
|
||||
@ -154,4 +142,42 @@ class UniqueOperationNamesTest extends ValidatorTestCase
|
||||
[new SourceLocation($l1, $c1), new SourceLocation($l2, $c2)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('multiple ops of same name of different types (mutation)')
|
||||
*/
|
||||
public function testMultipleOpsOfSameNameOfDifferentTypesMutation() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new UniqueOperationNames(),
|
||||
'
|
||||
query Foo {
|
||||
fieldA
|
||||
}
|
||||
mutation Foo {
|
||||
fieldB
|
||||
}
|
||||
',
|
||||
[$this->duplicateOp('Foo', 2, 13, 5, 16)]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('multiple ops of same name of different types (subscription)')
|
||||
*/
|
||||
public function testMultipleOpsOfSameNameOfDifferentTypesSubscription() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new UniqueOperationNames(),
|
||||
'
|
||||
query Foo {
|
||||
fieldA
|
||||
}
|
||||
subscription Foo {
|
||||
fieldB
|
||||
}
|
||||
',
|
||||
[$this->duplicateOp('Foo', 2, 13, 5, 20)]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,16 +11,18 @@ use GraphQL\Validator\Rules\UniqueVariableNames;
|
||||
class UniqueVariableNamesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Unique variable names
|
||||
|
||||
/**
|
||||
* @see it('unique variable names')
|
||||
*/
|
||||
public function testUniqueVariableNames() : void
|
||||
{
|
||||
$this->expectPassesRule(new UniqueVariableNames(), '
|
||||
$this->expectPassesRule(
|
||||
new UniqueVariableNames(),
|
||||
'
|
||||
query A($x: Int, $y: String) { __typename }
|
||||
query B($x: String, $y: Int) { __typename }
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,16 +30,20 @@ class UniqueVariableNamesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testDuplicateVariableNames() : void
|
||||
{
|
||||
$this->expectFailsRule(new UniqueVariableNames, '
|
||||
$this->expectFailsRule(
|
||||
new UniqueVariableNames(),
|
||||
'
|
||||
query A($x: Int, $x: Int, $x: String) { __typename }
|
||||
query B($x: String, $x: Int) { __typename }
|
||||
query C($x: Int, $x: Int) { __typename }
|
||||
', [
|
||||
$this->duplicateVariable('x', 2, 16, 2, 25),
|
||||
$this->duplicateVariable('x', 2, 16, 2, 34),
|
||||
$this->duplicateVariable('x', 3, 16, 3, 28),
|
||||
$this->duplicateVariable('x', 4, 16, 4, 25)
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->duplicateVariable('x', 2, 16, 2, 25),
|
||||
$this->duplicateVariable('x', 2, 16, 2, 34),
|
||||
$this->duplicateVariable('x', 3, 16, 3, 28),
|
||||
$this->duplicateVariable('x', 4, 16, 4, 25),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function duplicateVariable($name, $l1, $c1, $l2, $c2)
|
||||
|
@ -1,10 +1,12 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
class ValidationTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Supports full validation
|
||||
|
||||
/**
|
||||
* @see it('validates queries')
|
||||
*/
|
||||
@ -36,8 +38,8 @@ class ValidationTest extends ValidatorTestCase
|
||||
';
|
||||
|
||||
$expectedError = [
|
||||
'message' => "Expected type Invalid, found \"bad value\"; Invalid scalar is always invalid: bad value",
|
||||
'locations' => [ ['line' => 3, 'column' => 25] ]
|
||||
'message' => 'Expected type Invalid, found "bad value"; Invalid scalar is always invalid: bad value',
|
||||
'locations' => [['line' => 3, 'column' => 25]],
|
||||
];
|
||||
|
||||
$this->expectInvalid(
|
||||
@ -53,8 +55,8 @@ class ValidationTest extends ValidatorTestCase
|
||||
$query = '{invalid}';
|
||||
|
||||
$expectedError = [
|
||||
'message' => 'Cannot query field "invalid" on type "QueryRoot". Did you mean "invalidArg"?',
|
||||
'locations' => [ ['line' => 1, 'column' => 2] ]
|
||||
'message' => 'Cannot query field "invalid" on type "QueryRoot". Did you mean "invalidArg"?',
|
||||
'locations' => [['line' => 1, 'column' => 2]],
|
||||
];
|
||||
$this->expectFailsCompleteValidation($query, [$expectedError]);
|
||||
$this->expectValid($this->getTestSchema(), [], $query);
|
||||
|
@ -1,8 +1,10 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Language\Parser;
|
||||
use GraphQL\Type\Schema;
|
||||
use GraphQL\Type\Definition\CustomScalarType;
|
||||
use GraphQL\Type\Definition\Directive;
|
||||
use GraphQL\Type\Definition\EnumType;
|
||||
@ -11,11 +13,27 @@ use GraphQL\Type\Definition\InterfaceType;
|
||||
use GraphQL\Type\Definition\ObjectType;
|
||||
use GraphQL\Type\Definition\Type;
|
||||
use GraphQL\Type\Definition\UnionType;
|
||||
use GraphQL\Type\Schema;
|
||||
use GraphQL\Validator\DocumentValidator;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use function array_map;
|
||||
|
||||
abstract class ValidatorTestCase extends TestCase
|
||||
{
|
||||
protected function expectPassesRule($rule, $queryString) : void
|
||||
{
|
||||
$this->expectValid(self::getTestSchema(), [$rule], $queryString);
|
||||
}
|
||||
|
||||
protected function expectValid($schema, $rules, $queryString) : void
|
||||
{
|
||||
$this->assertEquals(
|
||||
[],
|
||||
DocumentValidator::validate($schema, Parser::parse($queryString), $rules),
|
||||
'Should validate'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Schema
|
||||
*/
|
||||
@ -24,198 +42,198 @@ abstract class ValidatorTestCase extends TestCase
|
||||
$FurColor = null;
|
||||
|
||||
$Being = new InterfaceType([
|
||||
'name' => 'Being',
|
||||
'name' => 'Being',
|
||||
'fields' => [
|
||||
'name' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['surname' => ['type' => Type::boolean()]]
|
||||
]
|
||||
'args' => ['surname' => ['type' => Type::boolean()]],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$Pet = new InterfaceType([
|
||||
'name' => 'Pet',
|
||||
'name' => 'Pet',
|
||||
'fields' => [
|
||||
'name' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['surname' => ['type' => Type::boolean()]]
|
||||
]
|
||||
'args' => ['surname' => ['type' => Type::boolean()]],
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
$Canine = new InterfaceType([
|
||||
'name' => 'Canine',
|
||||
'name' => 'Canine',
|
||||
'fields' => function () {
|
||||
return [
|
||||
'name' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['surname' => ['type' => Type::boolean()]]
|
||||
]
|
||||
'args' => ['surname' => ['type' => Type::boolean()]],
|
||||
],
|
||||
];
|
||||
}
|
||||
},
|
||||
]);
|
||||
|
||||
$DogCommand = new EnumType([
|
||||
'name' => 'DogCommand',
|
||||
'name' => 'DogCommand',
|
||||
'values' => [
|
||||
'SIT' => ['value' => 0],
|
||||
'SIT' => ['value' => 0],
|
||||
'HEEL' => ['value' => 1],
|
||||
'DOWN' => ['value' => 2]
|
||||
]
|
||||
'DOWN' => ['value' => 2],
|
||||
],
|
||||
]);
|
||||
|
||||
$Dog = new ObjectType([
|
||||
'name' => 'Dog',
|
||||
'fields' => [
|
||||
'name' => [
|
||||
'name' => 'Dog',
|
||||
'fields' => [
|
||||
'name' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['surname' => ['type' => Type::boolean()]]
|
||||
'args' => ['surname' => ['type' => Type::boolean()]],
|
||||
],
|
||||
'nickname' => ['type' => Type::string()],
|
||||
'barkVolume' => ['type' => Type::int()],
|
||||
'barks' => ['type' => Type::boolean()],
|
||||
'nickname' => ['type' => Type::string()],
|
||||
'barkVolume' => ['type' => Type::int()],
|
||||
'barks' => ['type' => Type::boolean()],
|
||||
'doesKnowCommand' => [
|
||||
'type' => Type::boolean(),
|
||||
'args' => ['dogCommand' => ['type' => $DogCommand]]
|
||||
'args' => ['dogCommand' => ['type' => $DogCommand]],
|
||||
],
|
||||
'isHousetrained' => [
|
||||
'isHousetrained' => [
|
||||
'type' => Type::boolean(),
|
||||
'args' => ['atOtherHomes' => ['type' => Type::boolean(), 'defaultValue' => true]]
|
||||
'args' => ['atOtherHomes' => ['type' => Type::boolean(), 'defaultValue' => true]],
|
||||
],
|
||||
'isAtLocation' => [
|
||||
'isAtLocation' => [
|
||||
'type' => Type::boolean(),
|
||||
'args' => ['x' => ['type' => Type::int()], 'y' => ['type' => Type::int()]]
|
||||
]
|
||||
'args' => ['x' => ['type' => Type::int()], 'y' => ['type' => Type::int()]],
|
||||
],
|
||||
],
|
||||
'interfaces' => [$Being, $Pet, $Canine]
|
||||
'interfaces' => [$Being, $Pet, $Canine],
|
||||
]);
|
||||
|
||||
$Cat = new ObjectType([
|
||||
'name' => 'Cat',
|
||||
'fields' => function () use (&$FurColor) {
|
||||
'name' => 'Cat',
|
||||
'fields' => function () use (&$FurColor) {
|
||||
return [
|
||||
'name' => [
|
||||
'name' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['surname' => ['type' => Type::boolean()]]
|
||||
'args' => ['surname' => ['type' => Type::boolean()]],
|
||||
],
|
||||
'nickname' => ['type' => Type::string()],
|
||||
'meows' => ['type' => Type::boolean()],
|
||||
'nickname' => ['type' => Type::string()],
|
||||
'meows' => ['type' => Type::boolean()],
|
||||
'meowVolume' => ['type' => Type::int()],
|
||||
'furColor' => $FurColor
|
||||
'furColor' => $FurColor,
|
||||
];
|
||||
},
|
||||
'interfaces' => [$Being, $Pet]
|
||||
'interfaces' => [$Being, $Pet],
|
||||
]);
|
||||
|
||||
$CatOrDog = new UnionType([
|
||||
'name' => 'CatOrDog',
|
||||
'name' => 'CatOrDog',
|
||||
'types' => [$Dog, $Cat],
|
||||
]);
|
||||
|
||||
$Intelligent = new InterfaceType([
|
||||
'name' => 'Intelligent',
|
||||
'name' => 'Intelligent',
|
||||
'fields' => [
|
||||
'iq' => ['type' => Type::int()]
|
||||
]
|
||||
'iq' => ['type' => Type::int()],
|
||||
],
|
||||
]);
|
||||
|
||||
$Human = null;
|
||||
$Human = new ObjectType([
|
||||
'name' => 'Human',
|
||||
'name' => 'Human',
|
||||
'interfaces' => [$Being, $Intelligent],
|
||||
'fields' => function () use (&$Human, $Pet) {
|
||||
'fields' => function () use (&$Human, $Pet) {
|
||||
return [
|
||||
'name' => [
|
||||
'name' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['surname' => ['type' => Type::boolean()]]
|
||||
'args' => ['surname' => ['type' => Type::boolean()]],
|
||||
],
|
||||
'pets' => ['type' => Type::listOf($Pet)],
|
||||
'pets' => ['type' => Type::listOf($Pet)],
|
||||
'relatives' => ['type' => Type::listOf($Human)],
|
||||
'iq' => ['type' => Type::int()]
|
||||
'iq' => ['type' => Type::int()],
|
||||
];
|
||||
}
|
||||
},
|
||||
]);
|
||||
|
||||
$Alien = new ObjectType([
|
||||
'name' => 'Alien',
|
||||
'name' => 'Alien',
|
||||
'interfaces' => [$Being, $Intelligent],
|
||||
'fields' => [
|
||||
'iq' => ['type' => Type::int()],
|
||||
'name' => [
|
||||
'fields' => [
|
||||
'iq' => ['type' => Type::int()],
|
||||
'name' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['surname' => ['type' => Type::boolean()]]
|
||||
'args' => ['surname' => ['type' => Type::boolean()]],
|
||||
],
|
||||
'numEyes' => ['type' => Type::int()]
|
||||
]
|
||||
'numEyes' => ['type' => Type::int()],
|
||||
],
|
||||
]);
|
||||
|
||||
$DogOrHuman = new UnionType([
|
||||
'name' => 'DogOrHuman',
|
||||
'name' => 'DogOrHuman',
|
||||
'types' => [$Dog, $Human],
|
||||
]);
|
||||
|
||||
$HumanOrAlien = new UnionType([
|
||||
'name' => 'HumanOrAlien',
|
||||
'name' => 'HumanOrAlien',
|
||||
'types' => [$Human, $Alien],
|
||||
]);
|
||||
|
||||
$FurColor = new EnumType([
|
||||
'name' => 'FurColor',
|
||||
'name' => 'FurColor',
|
||||
'values' => [
|
||||
'BROWN' => ['value' => 0],
|
||||
'BLACK' => ['value' => 1],
|
||||
'TAN' => ['value' => 2],
|
||||
'BROWN' => ['value' => 0],
|
||||
'BLACK' => ['value' => 1],
|
||||
'TAN' => ['value' => 2],
|
||||
'SPOTTED' => ['value' => 3],
|
||||
'NO_FUR' => ['value' => null],
|
||||
'NO_FUR' => ['value' => null],
|
||||
],
|
||||
]);
|
||||
|
||||
$ComplexInput = new InputObjectType([
|
||||
'name' => 'ComplexInput',
|
||||
'name' => 'ComplexInput',
|
||||
'fields' => [
|
||||
'requiredField' => ['type' => Type::nonNull(Type::boolean())],
|
||||
'intField' => ['type' => Type::int()],
|
||||
'stringField' => ['type' => Type::string()],
|
||||
'booleanField' => ['type' => Type::boolean()],
|
||||
'stringListField' => ['type' => Type::listOf(Type::string())]
|
||||
]
|
||||
'requiredField' => ['type' => Type::nonNull(Type::boolean())],
|
||||
'intField' => ['type' => Type::int()],
|
||||
'stringField' => ['type' => Type::string()],
|
||||
'booleanField' => ['type' => Type::boolean()],
|
||||
'stringListField' => ['type' => Type::listOf(Type::string())],
|
||||
],
|
||||
]);
|
||||
|
||||
$ComplicatedArgs = new ObjectType([
|
||||
'name' => 'ComplicatedArgs',
|
||||
'name' => 'ComplicatedArgs',
|
||||
// TODO List
|
||||
// TODO Coercion
|
||||
// TODO NotNulls
|
||||
'fields' => [
|
||||
'intArgField' => [
|
||||
'intArgField' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['intArg' => ['type' => Type::int()]],
|
||||
],
|
||||
'nonNullIntArgField' => [
|
||||
'nonNullIntArgField' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['nonNullIntArg' => ['type' => Type::nonNull(Type::int())]],
|
||||
],
|
||||
'stringArgField' => [
|
||||
'stringArgField' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['stringArg' => ['type' => Type::string()]],
|
||||
],
|
||||
'booleanArgField' => [
|
||||
'booleanArgField' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['booleanArg' => ['type' => Type::boolean()]],
|
||||
],
|
||||
'enumArgField' => [
|
||||
'enumArgField' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['enumArg' => ['type' => $FurColor]],
|
||||
],
|
||||
'floatArgField' => [
|
||||
'floatArgField' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['floatArg' => ['type' => Type::float()]],
|
||||
],
|
||||
'idArgField' => [
|
||||
'idArgField' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['idArg' => ['type' => Type::id()]],
|
||||
],
|
||||
'stringListArgField' => [
|
||||
'stringListArgField' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['stringListArg' => ['type' => Type::listOf(Type::string())]],
|
||||
],
|
||||
@ -227,194 +245,191 @@ abstract class ValidatorTestCase extends TestCase
|
||||
],
|
||||
],
|
||||
],
|
||||
'complexArgField' => [
|
||||
'complexArgField' => [
|
||||
'type' => Type::string(),
|
||||
'args' => ['complexArg' => ['type' => $ComplexInput]],
|
||||
],
|
||||
'multipleReqs' => [
|
||||
'multipleReqs' => [
|
||||
'type' => Type::string(),
|
||||
'args' => [
|
||||
'req1' => ['type' => Type::nonNull(Type::int())],
|
||||
'req2' => ['type' => Type::nonNull(Type::int())],
|
||||
],
|
||||
],
|
||||
'multipleOpts' => [
|
||||
'multipleOpts' => [
|
||||
'type' => Type::string(),
|
||||
'args' => [
|
||||
'opt1' => [
|
||||
'type' => Type::int(),
|
||||
'type' => Type::int(),
|
||||
'defaultValue' => 0,
|
||||
],
|
||||
'opt2' => [
|
||||
'type' => Type::int(),
|
||||
'type' => Type::int(),
|
||||
'defaultValue' => 0,
|
||||
],
|
||||
],
|
||||
],
|
||||
'multipleOptAndReq' => [
|
||||
'multipleOptAndReq' => [
|
||||
'type' => Type::string(),
|
||||
'args' => [
|
||||
'req1' => ['type' => Type::nonNull(Type::int())],
|
||||
'req2' => ['type' => Type::nonNull(Type::int())],
|
||||
'opt1' => [
|
||||
'type' => Type::int(),
|
||||
'type' => Type::int(),
|
||||
'defaultValue' => 0,
|
||||
],
|
||||
'opt2' => [
|
||||
'type' => Type::int(),
|
||||
'type' => Type::int(),
|
||||
'defaultValue' => 0,
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$invalidScalar = new CustomScalarType([
|
||||
'name' => 'Invalid',
|
||||
'serialize' => function ($value) {
|
||||
'name' => 'Invalid',
|
||||
'serialize' => function ($value) {
|
||||
return $value;
|
||||
},
|
||||
'parseLiteral' => function ($node) {
|
||||
throw new \Exception('Invalid scalar is always invalid: ' . $node->value);
|
||||
},
|
||||
'parseValue' => function ($node) {
|
||||
'parseValue' => function ($node) {
|
||||
throw new \Exception('Invalid scalar is always invalid: ' . $node);
|
||||
},
|
||||
]);
|
||||
|
||||
$anyScalar = new CustomScalarType([
|
||||
'name' => 'Any',
|
||||
'serialize' => function ($value) {
|
||||
'name' => 'Any',
|
||||
'serialize' => function ($value) {
|
||||
return $value;
|
||||
},
|
||||
'parseLiteral' => function ($node) {
|
||||
return $node;
|
||||
}, // Allows any value
|
||||
'parseValue' => function ($value) {
|
||||
'parseValue' => function ($value) {
|
||||
return $value;
|
||||
}, // Allows any value
|
||||
]);
|
||||
|
||||
$queryRoot = new ObjectType([
|
||||
'name' => 'QueryRoot',
|
||||
'name' => 'QueryRoot',
|
||||
'fields' => [
|
||||
'human' => [
|
||||
'human' => [
|
||||
'args' => ['id' => ['type' => Type::id()]],
|
||||
'type' => $Human
|
||||
'type' => $Human,
|
||||
],
|
||||
'alien' => ['type' => $Alien],
|
||||
'dog' => ['type' => $Dog],
|
||||
'cat' => ['type' => $Cat],
|
||||
'pet' => ['type' => $Pet],
|
||||
'catOrDog' => ['type' => $CatOrDog],
|
||||
'dogOrHuman' => ['type' => $DogOrHuman],
|
||||
'humanOrAlien' => ['type' => $HumanOrAlien],
|
||||
'alien' => ['type' => $Alien],
|
||||
'dog' => ['type' => $Dog],
|
||||
'cat' => ['type' => $Cat],
|
||||
'pet' => ['type' => $Pet],
|
||||
'catOrDog' => ['type' => $CatOrDog],
|
||||
'dogOrHuman' => ['type' => $DogOrHuman],
|
||||
'humanOrAlien' => ['type' => $HumanOrAlien],
|
||||
'complicatedArgs' => ['type' => $ComplicatedArgs],
|
||||
'invalidArg' => [
|
||||
'invalidArg' => [
|
||||
'args' => [
|
||||
'arg' => ['type' => $invalidScalar]
|
||||
'arg' => ['type' => $invalidScalar],
|
||||
],
|
||||
'type' => Type::string(),
|
||||
],
|
||||
'anyArg' => [
|
||||
'anyArg' => [
|
||||
'args' => ['arg' => ['type' => $anyScalar]],
|
||||
'type' => Type::string(),
|
||||
],
|
||||
]
|
||||
],
|
||||
]);
|
||||
|
||||
$testSchema = new Schema([
|
||||
'query' => $queryRoot,
|
||||
'query' => $queryRoot,
|
||||
'directives' => [
|
||||
Directive::includeDirective(),
|
||||
Directive::skipDirective(),
|
||||
new Directive([
|
||||
'name' => 'onQuery',
|
||||
'name' => 'onQuery',
|
||||
'locations' => ['QUERY'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onMutation',
|
||||
'name' => 'onMutation',
|
||||
'locations' => ['MUTATION'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onSubscription',
|
||||
'name' => 'onSubscription',
|
||||
'locations' => ['SUBSCRIPTION'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onField',
|
||||
'name' => 'onField',
|
||||
'locations' => ['FIELD'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onFragmentDefinition',
|
||||
'name' => 'onFragmentDefinition',
|
||||
'locations' => ['FRAGMENT_DEFINITION'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onFragmentSpread',
|
||||
'name' => 'onFragmentSpread',
|
||||
'locations' => ['FRAGMENT_SPREAD'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onInlineFragment',
|
||||
'name' => 'onInlineFragment',
|
||||
'locations' => ['INLINE_FRAGMENT'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onSchema',
|
||||
'name' => 'onSchema',
|
||||
'locations' => ['SCHEMA'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onScalar',
|
||||
'name' => 'onScalar',
|
||||
'locations' => ['SCALAR'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onObject',
|
||||
'name' => 'onObject',
|
||||
'locations' => ['OBJECT'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onFieldDefinition',
|
||||
'name' => 'onFieldDefinition',
|
||||
'locations' => ['FIELD_DEFINITION'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onArgumentDefinition',
|
||||
'name' => 'onArgumentDefinition',
|
||||
'locations' => ['ARGUMENT_DEFINITION'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onInterface',
|
||||
'name' => 'onInterface',
|
||||
'locations' => ['INTERFACE'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onUnion',
|
||||
'name' => 'onUnion',
|
||||
'locations' => ['UNION'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onEnum',
|
||||
'name' => 'onEnum',
|
||||
'locations' => ['ENUM'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onEnumValue',
|
||||
'name' => 'onEnumValue',
|
||||
'locations' => ['ENUM_VALUE'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onInputObject',
|
||||
'name' => 'onInputObject',
|
||||
'locations' => ['INPUT_OBJECT'],
|
||||
]),
|
||||
new Directive([
|
||||
'name' => 'onInputFieldDefinition',
|
||||
'name' => 'onInputFieldDefinition',
|
||||
'locations' => ['INPUT_FIELD_DEFINITION'],
|
||||
]),
|
||||
],
|
||||
]);
|
||||
|
||||
return $testSchema;
|
||||
}
|
||||
|
||||
function expectValid($schema, $rules, $queryString)
|
||||
protected function expectFailsRule($rule, $queryString, $errors)
|
||||
{
|
||||
$this->assertEquals(
|
||||
[],
|
||||
DocumentValidator::validate($schema, Parser::parse($queryString), $rules),
|
||||
'Should validate'
|
||||
);
|
||||
return $this->expectInvalid(self::getTestSchema(), [$rule], $queryString, $errors);
|
||||
}
|
||||
|
||||
function expectInvalid($schema, $rules, $queryString, $expectedErrors)
|
||||
protected function expectInvalid($schema, $rules, $queryString, $expectedErrors)
|
||||
{
|
||||
$errors = DocumentValidator::validate($schema, Parser::parse($queryString), $rules);
|
||||
|
||||
@ -424,33 +439,23 @@ abstract class ValidatorTestCase extends TestCase
|
||||
return $errors;
|
||||
}
|
||||
|
||||
function expectPassesRule($rule, $queryString)
|
||||
{
|
||||
$this->expectValid($this->getTestSchema(), [$rule], $queryString);
|
||||
}
|
||||
|
||||
function expectFailsRule($rule, $queryString, $errors)
|
||||
{
|
||||
return $this->expectInvalid($this->getTestSchema(), [$rule], $queryString, $errors);
|
||||
}
|
||||
|
||||
function expectPassesRuleWithSchema($schema, $rule, $queryString)
|
||||
protected function expectPassesRuleWithSchema($schema, $rule, $queryString) : void
|
||||
{
|
||||
$this->expectValid($schema, [$rule], $queryString);
|
||||
}
|
||||
|
||||
function expectFailsRuleWithSchema($schema, $rule, $queryString, $errors)
|
||||
protected function expectFailsRuleWithSchema($schema, $rule, $queryString, $errors) : void
|
||||
{
|
||||
$this->expectInvalid($schema, [$rule], $queryString, $errors);
|
||||
}
|
||||
|
||||
function expectPassesCompleteValidation($queryString)
|
||||
protected function expectPassesCompleteValidation($queryString) : void
|
||||
{
|
||||
$this->expectValid($this->getTestSchema(), DocumentValidator::allRules(), $queryString);
|
||||
$this->expectValid(self::getTestSchema(), DocumentValidator::allRules(), $queryString);
|
||||
}
|
||||
|
||||
function expectFailsCompleteValidation($queryString, $errors)
|
||||
protected function expectFailsCompleteValidation($queryString, $errors) : void
|
||||
{
|
||||
$this->expectInvalid($this->getTestSchema(), DocumentValidator::allRules(), $queryString, $errors);
|
||||
$this->expectInvalid(self::getTestSchema(), DocumentValidator::allRules(), $queryString, $errors);
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,17 +11,19 @@ use GraphQL\Validator\Rules\VariablesAreInputTypes;
|
||||
class VariablesAreInputTypesTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Variables are input types
|
||||
|
||||
/**
|
||||
* @see it('input types are valid')
|
||||
*/
|
||||
public function testInputTypesAreValid() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesAreInputTypes(), '
|
||||
$this->expectPassesRule(
|
||||
new VariablesAreInputTypes(),
|
||||
'
|
||||
query Foo($a: String, $b: [Boolean!]!, $c: ComplexInput) {
|
||||
field(a: $a, b: $b, c: $c)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -26,11 +31,14 @@ class VariablesAreInputTypesTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testOutputTypesAreInvalid() : void
|
||||
{
|
||||
$this->expectFailsRule(new VariablesAreInputTypes, '
|
||||
$this->expectFailsRule(
|
||||
new VariablesAreInputTypes(),
|
||||
'
|
||||
query Foo($a: Dog, $b: [[CatOrDog!]]!, $c: Pet) {
|
||||
field(a: $a, b: $b, c: $c)
|
||||
}
|
||||
', [
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
VariablesAreInputTypes::nonInputTypeOnVarMessage('a', 'Dog'),
|
||||
[new SourceLocation(2, 21)]
|
||||
@ -42,7 +50,7 @@ class VariablesAreInputTypesTest extends ValidatorTestCase
|
||||
FormattedError::create(
|
||||
VariablesAreInputTypes::nonInputTypeOnVarMessage('c', 'Pet'),
|
||||
[new SourceLocation(2, 50)]
|
||||
)
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -7,6 +10,95 @@ use GraphQL\Validator\Rules\VariablesDefaultValueAllowed;
|
||||
|
||||
class VariablesDefaultValueAllowedTest extends ValidatorTestCase
|
||||
{
|
||||
/**
|
||||
* @see it('variables with no default values')
|
||||
*/
|
||||
public function testVariablesWithNoDefaultValues() : void
|
||||
{
|
||||
$this->expectPassesRule(
|
||||
new VariablesDefaultValueAllowed(),
|
||||
'
|
||||
query NullableValues($a: Int, $b: String, $c: ComplexInput) {
|
||||
dog { name }
|
||||
}
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
// DESCRIBE: Validate: Variable default value is allowed
|
||||
|
||||
/**
|
||||
* @see it('required variables without default values')
|
||||
*/
|
||||
public function testRequiredVariablesWithoutDefaultValues() : void
|
||||
{
|
||||
$this->expectPassesRule(
|
||||
new VariablesDefaultValueAllowed(),
|
||||
'
|
||||
query RequiredValues($a: Int!, $b: String!) {
|
||||
dog { name }
|
||||
}
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('variables with valid default values')
|
||||
*/
|
||||
public function testVariablesWithValidDefaultValues() : void
|
||||
{
|
||||
$this->expectPassesRule(
|
||||
new VariablesDefaultValueAllowed(),
|
||||
'
|
||||
query WithDefaultValues(
|
||||
$a: Int = 1,
|
||||
$b: String = "ok",
|
||||
$c: ComplexInput = { requiredField: true, intField: 3 }
|
||||
) {
|
||||
dog { name }
|
||||
}
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('variables with valid default null values')
|
||||
*/
|
||||
public function testVariablesWithValidDefaultNullValues() : void
|
||||
{
|
||||
$this->expectPassesRule(
|
||||
new VariablesDefaultValueAllowed(),
|
||||
'
|
||||
query WithDefaultValues(
|
||||
$a: Int = null,
|
||||
$b: String = null,
|
||||
$c: ComplexInput = { requiredField: true, intField: null }
|
||||
) {
|
||||
dog { name }
|
||||
}
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('no required variables with default values')
|
||||
*/
|
||||
public function testNoRequiredVariablesWithDefaultValues() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new VariablesDefaultValueAllowed(),
|
||||
'
|
||||
query UnreachableDefaultValues($a: Int! = 3, $b: String! = "default") {
|
||||
dog { name }
|
||||
}
|
||||
',
|
||||
[
|
||||
$this->defaultForRequiredVar('a', 'Int!', 'Int', 2, 49),
|
||||
$this->defaultForRequiredVar('b', 'String!', 'String', 2, 66),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
private function defaultForRequiredVar($varName, $typeName, $guessTypeName, $line, $column)
|
||||
{
|
||||
return FormattedError::create(
|
||||
@ -19,91 +111,22 @@ class VariablesDefaultValueAllowedTest extends ValidatorTestCase
|
||||
);
|
||||
}
|
||||
|
||||
// DESCRIBE: Validate: Variable default value is allowed
|
||||
|
||||
/**
|
||||
* @see it('variables with no default values')
|
||||
*/
|
||||
public function testVariablesWithNoDefaultValues() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesDefaultValueAllowed(), '
|
||||
query NullableValues($a: Int, $b: String, $c: ComplexInput) {
|
||||
dog { name }
|
||||
}
|
||||
');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('required variables without default values')
|
||||
*/
|
||||
public function testRequiredVariablesWithoutDefaultValues() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesDefaultValueAllowed(), '
|
||||
query RequiredValues($a: Int!, $b: String!) {
|
||||
dog { name }
|
||||
}
|
||||
');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('variables with valid default values')
|
||||
*/
|
||||
public function testVariablesWithValidDefaultValues() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesDefaultValueAllowed(), '
|
||||
query WithDefaultValues(
|
||||
$a: Int = 1,
|
||||
$b: String = "ok",
|
||||
$c: ComplexInput = { requiredField: true, intField: 3 }
|
||||
) {
|
||||
dog { name }
|
||||
}
|
||||
');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('variables with valid default null values')
|
||||
*/
|
||||
public function testVariablesWithValidDefaultNullValues() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesDefaultValueAllowed(), '
|
||||
query WithDefaultValues(
|
||||
$a: Int = null,
|
||||
$b: String = null,
|
||||
$c: ComplexInput = { requiredField: true, intField: null }
|
||||
) {
|
||||
dog { name }
|
||||
}
|
||||
');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('no required variables with default values')
|
||||
*/
|
||||
public function testNoRequiredVariablesWithDefaultValues() : void
|
||||
{
|
||||
$this->expectFailsRule(new VariablesDefaultValueAllowed(), '
|
||||
query UnreachableDefaultValues($a: Int! = 3, $b: String! = "default") {
|
||||
dog { name }
|
||||
}
|
||||
', [
|
||||
$this->defaultForRequiredVar('a', 'Int!', 'Int', 2, 49),
|
||||
$this->defaultForRequiredVar('b', 'String!', 'String', 2, 66),
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see it('variables with invalid default null values')
|
||||
*/
|
||||
public function testNullIntoNullableType() : void
|
||||
{
|
||||
$this->expectFailsRule(new VariablesDefaultValueAllowed(), '
|
||||
$this->expectFailsRule(
|
||||
new VariablesDefaultValueAllowed(),
|
||||
'
|
||||
query WithDefaultValues($a: Int! = null, $b: String! = null) {
|
||||
dog { name }
|
||||
}
|
||||
', [
|
||||
$this->defaultForRequiredVar('a', 'Int!', 'Int', 2, 42),
|
||||
$this->defaultForRequiredVar('b', 'String!', 'String', 2, 62),
|
||||
]);
|
||||
',
|
||||
[
|
||||
$this->defaultForRequiredVar('a', 'Int!', 'Int', 2, 42),
|
||||
$this->defaultForRequiredVar('b', 'String!', 'String', 2, 62),
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,4 +1,7 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace GraphQL\Tests\Validator;
|
||||
|
||||
use GraphQL\Error\FormattedError;
|
||||
@ -8,21 +11,23 @@ use GraphQL\Validator\Rules\VariablesInAllowedPosition;
|
||||
class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
{
|
||||
// Validate: Variables are in allowed positions
|
||||
|
||||
/**
|
||||
* @see it('Boolean => Boolean')
|
||||
*/
|
||||
public function testBooleanXBoolean() : void
|
||||
{
|
||||
// Boolean => Boolean
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition(), '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($booleanArg: Boolean)
|
||||
{
|
||||
complicatedArgs {
|
||||
booleanArgField(booleanArg: $booleanArg)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,7 +36,9 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
public function testBooleanXBooleanWithinFragment() : void
|
||||
{
|
||||
// Boolean => Boolean within fragment
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
fragment booleanArgFrag on ComplicatedArgs {
|
||||
booleanArgField(booleanArg: $booleanArg)
|
||||
}
|
||||
@ -41,9 +48,12 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
...booleanArgFrag
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($booleanArg: Boolean)
|
||||
{
|
||||
complicatedArgs {
|
||||
@ -53,7 +63,8 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
fragment booleanArgFrag on ComplicatedArgs {
|
||||
booleanArgField(booleanArg: $booleanArg)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -62,14 +73,17 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
public function testBooleanNonNullXBoolean() : void
|
||||
{
|
||||
// Boolean! => Boolean
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($nonNullBooleanArg: Boolean!)
|
||||
{
|
||||
complicatedArgs {
|
||||
booleanArgField(booleanArg: $nonNullBooleanArg)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -78,7 +92,9 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
public function testBooleanNonNullXBooleanWithinFragment() : void
|
||||
{
|
||||
// Boolean! => Boolean within fragment
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
fragment booleanArgFrag on ComplicatedArgs {
|
||||
booleanArgField(booleanArg: $nonNullBooleanArg)
|
||||
}
|
||||
@ -89,7 +105,8 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
...booleanArgFrag
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -98,14 +115,17 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
public function testIntXIntNonNullWithDefault() : void
|
||||
{
|
||||
// Int => Int! with default
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($intArg: Int = 1)
|
||||
{
|
||||
complicatedArgs {
|
||||
nonNullIntArgField(nonNullIntArg: $intArg)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -113,14 +133,17 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testListOfStringXListOfString() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($stringListVar: [String])
|
||||
{
|
||||
complicatedArgs {
|
||||
stringListArgField(stringListArg: $stringListVar)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -128,14 +151,17 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testListOfStringNonNullXListOfString() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($stringListVar: [String!])
|
||||
{
|
||||
complicatedArgs {
|
||||
stringListArgField(stringListArg: $stringListVar)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -143,14 +169,17 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testStringXListOfStringInItemPosition() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($stringVar: String)
|
||||
{
|
||||
complicatedArgs {
|
||||
stringListArgField(stringListArg: [$stringVar])
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -158,14 +187,17 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testStringNonNullXListOfStringInItemPosition() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($stringVar: String!)
|
||||
{
|
||||
complicatedArgs {
|
||||
stringListArgField(stringListArg: [$stringVar])
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -173,14 +205,17 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testComplexInputXComplexInput() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($complexVar: ComplexInput)
|
||||
{
|
||||
complicatedArgs {
|
||||
complexArgField(complexArg: $ComplexInput)
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -188,14 +223,17 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testComplexInputXComplexInputInFieldPosition() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($boolVar: Boolean = false)
|
||||
{
|
||||
complicatedArgs {
|
||||
complexArgField(complexArg: {requiredArg: $boolVar})
|
||||
}
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -203,12 +241,15 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testBooleanNonNullXBooleanNonNullInDirective() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($boolVar: Boolean!)
|
||||
{
|
||||
dog @include(if: $boolVar)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -216,12 +257,15 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testBooleanXBooleanNonNullInDirectiveWithDefault() : void
|
||||
{
|
||||
$this->expectPassesRule(new VariablesInAllowedPosition, '
|
||||
$this->expectPassesRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($boolVar: Boolean = false)
|
||||
{
|
||||
dog @include(if: $boolVar)
|
||||
}
|
||||
');
|
||||
'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -229,18 +273,22 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testIntXIntNonNull() : void
|
||||
{
|
||||
$this->expectFailsRule(new VariablesInAllowedPosition, '
|
||||
$this->expectFailsRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($intArg: Int) {
|
||||
complicatedArgs {
|
||||
nonNullIntArgField(nonNullIntArg: $intArg)
|
||||
}
|
||||
}
|
||||
', [
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('intArg', 'Int', 'Int!'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(4, 45)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('intArg', 'Int', 'Int!'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(4, 45)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -248,7 +296,9 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testIntXIntNonNullWithinFragment() : void
|
||||
{
|
||||
$this->expectFailsRule(new VariablesInAllowedPosition, '
|
||||
$this->expectFailsRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
fragment nonNullIntArgFieldFrag on ComplicatedArgs {
|
||||
nonNullIntArgField(nonNullIntArg: $intArg)
|
||||
}
|
||||
@ -258,12 +308,14 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
...nonNullIntArgFieldFrag
|
||||
}
|
||||
}
|
||||
', [
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('intArg', 'Int', 'Int!'),
|
||||
[new SourceLocation(6, 19), new SourceLocation(3, 43)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('intArg', 'Int', 'Int!'),
|
||||
[new SourceLocation(6, 19), new SourceLocation(3, 43)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -272,7 +324,9 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
public function testIntXIntNonNullWithinNestedFragment() : void
|
||||
{
|
||||
// Int => Int! within nested fragment
|
||||
$this->expectFailsRule(new VariablesInAllowedPosition, '
|
||||
$this->expectFailsRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
fragment outerFrag on ComplicatedArgs {
|
||||
...nonNullIntArgFieldFrag
|
||||
}
|
||||
@ -287,12 +341,14 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
...outerFrag
|
||||
}
|
||||
}
|
||||
', [
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('intArg', 'Int', 'Int!'),
|
||||
[new SourceLocation(10, 19), new SourceLocation(7,43)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('intArg', 'Int', 'Int!'),
|
||||
[new SourceLocation(10, 19), new SourceLocation(7, 43)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -300,18 +356,22 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testStringOverBoolean() : void
|
||||
{
|
||||
$this->expectFailsRule(new VariablesInAllowedPosition, '
|
||||
$this->expectFailsRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($stringVar: String) {
|
||||
complicatedArgs {
|
||||
booleanArgField(booleanArg: $stringVar)
|
||||
}
|
||||
}
|
||||
', [
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('stringVar', 'String', 'Boolean'),
|
||||
[new SourceLocation(2,19), new SourceLocation(4,39)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('stringVar', 'String', 'Boolean'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(4, 39)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -319,18 +379,22 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testStringXListOfString() : void
|
||||
{
|
||||
$this->expectFailsRule(new VariablesInAllowedPosition, '
|
||||
$this->expectFailsRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($stringVar: String) {
|
||||
complicatedArgs {
|
||||
stringListArgField(stringListArg: $stringVar)
|
||||
}
|
||||
}
|
||||
', [
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('stringVar', 'String', '[String]'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(4,45)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('stringVar', 'String', '[String]'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(4, 45)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,16 +402,20 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
*/
|
||||
public function testBooleanXBooleanNonNullInDirective() : void
|
||||
{
|
||||
$this->expectFailsRule(new VariablesInAllowedPosition, '
|
||||
$this->expectFailsRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($boolVar: Boolean) {
|
||||
dog @include(if: $boolVar)
|
||||
}
|
||||
', [
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('boolVar', 'Boolean', 'Boolean!'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(3,26)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('boolVar', 'Boolean', 'Boolean!'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(3, 26)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -356,16 +424,20 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
public function testStringXBooleanNonNullInDirective() : void
|
||||
{
|
||||
// String => Boolean! in directive
|
||||
$this->expectFailsRule(new VariablesInAllowedPosition, '
|
||||
$this->expectFailsRule(
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($stringVar: String) {
|
||||
dog @include(if: $stringVar)
|
||||
}
|
||||
', [
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('stringVar', 'String', 'Boolean!'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(3,26)]
|
||||
)
|
||||
]);
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('stringVar', 'String', 'Boolean!'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(3, 26)]
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -374,7 +446,7 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
public function testStringArrayXStringNonNullArray() : void
|
||||
{
|
||||
$this->expectFailsRule(
|
||||
new VariablesInAllowedPosition,
|
||||
new VariablesInAllowedPosition(),
|
||||
'
|
||||
query Query($stringListVar: [String])
|
||||
{
|
||||
@ -382,11 +454,12 @@ class VariablesInAllowedPositionTest extends ValidatorTestCase
|
||||
stringListNonNullArgField(stringListNonNullArg: $stringListVar)
|
||||
}
|
||||
}
|
||||
', [
|
||||
',
|
||||
[
|
||||
FormattedError::create(
|
||||
VariablesInAllowedPosition::badVarPosMessage('stringListVar', '[String]', '[String!]'),
|
||||
[new SourceLocation(2, 19), new SourceLocation(5, 59)]
|
||||
)
|
||||
),
|
||||
]
|
||||
);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user