graphql-php/tests/Validator/NoFragmentCyclesTest.php
2015-07-15 23:05:46 +06:00

190 lines
5.5 KiB
PHP

<?php
namespace GraphQL\Validator;
use GraphQL\FormattedError;
use GraphQL\Language\Source;
use GraphQL\Language\SourceLocation;
use GraphQL\Type\Definition\Config;
use GraphQL\Validator\Rules\NoFragmentCycles;
class NoFragmentCyclesTest extends TestCase
{
// Validate: No circular fragment spreads
public function testSingleReferenceIsValid()
{
$this->expectPassesRule(new NoFragmentCycles(), '
fragment fragA on Dog { ...fragB }
fragment fragB on Dog { name }
');
}
public function testSpreadingTwiceIsNotCircular()
{
$this->expectPassesRule(new NoFragmentCycles, '
fragment fragA on Dog { ...fragB, ...fragB }
fragment fragB on Dog { name }
');
}
public function testSpreadingTwiceIndirectlyIsNotCircular()
{
$this->expectPassesRule(new NoFragmentCycles, '
fragment fragA on Dog { ...fragB, ...fragC }
fragment fragB on Dog { ...fragC }
fragment fragC on Dog { name }
');
}
public function testDoubleSpreadWithinAbstractTypes()
{
$this->expectPassesRule(new NoFragmentCycles, '
fragment nameFragment on Pet {
... on Dog { name }
... on Cat { name }
}
fragment spreadsInAnon on Pet {
... on Dog { ...nameFragment }
... on Cat { ...nameFragment }
}
');
}
public function testSpreadingRecursivelyWithinFieldFails()
{
$this->expectFailsRule(new NoFragmentCycles, '
fragment fragA on Human { relatives { ...fragA } },
', [
$this->cycleError('fragA', [], 2, 45)
]);
}
public function testNoSpreadingItselfDirectly()
{
$this->expectFailsRule(new NoFragmentCycles, '
fragment fragA on Dog { ...fragA }
', [
$this->cycleError('fragA', [], 2, 31)
]);
}
public function testNoSpreadingItselfDirectlyWithinInlineFragment()
{
$this->expectFailsRule(new NoFragmentCycles, '
fragment fragA on Pet {
... on Dog {
...fragA
}
}
', [
$this->cycleError('fragA', [], 4, 11)
]);
}
public function testNoSpreadingItselfIndirectly()
{
$this->expectFailsRule(new NoFragmentCycles, '
fragment fragA on Dog { ...fragB }
fragment fragB on Dog { ...fragA }
', [
new FormattedError(
Messages::cycleErrorMessage('fragA', ['fragB']),
[ new SourceLocation(2, 31), new SourceLocation(3, 31) ]
)
]);
}
public function testNoSpreadingItselfIndirectlyReportsOppositeOrder()
{
$this->expectFailsRule(new NoFragmentCycles, '
fragment fragB on Dog { ...fragA }
fragment fragA on Dog { ...fragB }
', [
new FormattedError(
Messages::cycleErrorMessage('fragB', ['fragA']),
[new SourceLocation(2, 31), new SourceLocation(3, 31)]
)
]);
}
public function testNoSpreadingItselfIndirectlyWithinInlineFragment()
{
$this->expectFailsRule(new NoFragmentCycles, '
fragment fragA on Pet {
... on Dog {
...fragB
}
}
fragment fragB on Pet {
... on Dog {
...fragA
}
}
', [
new FormattedError(
Messages::cycleErrorMessage('fragA', ['fragB']),
[new SourceLocation(4, 11), new SourceLocation(9, 11)]
)
]);
}
public function testNoSpreadingItselfDeeply()
{
$this->expectFailsRule(new NoFragmentCycles, '
fragment fragA on Dog { ...fragB }
fragment fragB on Dog { ...fragC }
fragment fragC on Dog { ...fragO }
fragment fragX on Dog { ...fragY }
fragment fragY on Dog { ...fragZ }
fragment fragZ on Dog { ...fragO }
fragment fragO on Dog { ...fragA, ...fragX }
', [
new FormattedError(
Messages::cycleErrorMessage('fragA', ['fragB', 'fragC', 'fragO']),
[
new SourceLocation(2, 31),
new SourceLocation(3, 31),
new SourceLocation(4, 31),
new SourceLocation(8, 31),
]
),
new FormattedError(
Messages::cycleErrorMessage('fragX', ['fragY', 'fragZ', 'fragO']),
[
new SourceLocation(5, 31),
new SourceLocation(6, 31),
new SourceLocation(7, 31),
new SourceLocation(8, 41),
]
)
]);
}
public function testNoSpreadingItselfDeeplyTwoPathsNewRule()
{
$this->expectFailsRule(new NoFragmentCycles, '
fragment fragA on Dog { ...fragB, ...fragC }
fragment fragB on Dog { ...fragA }
fragment fragC on Dog { ...fragA }
', [
new FormattedError(
'Cannot spread fragment fragA within itself via fragB.',
[new SourceLocation(2, 31), new SourceLocation(3, 31)]
),
new FormattedError(
'Cannot spread fragment fragA within itself via fragC.',
[new SourceLocation(2, 41), new SourceLocation(4, 31)]
)
]);
}
private function cycleError($fargment, $spreadNames, $line, $column)
{
return new FormattedError(
Messages::cycleErrorMessage($fargment, $spreadNames),
[new SourceLocation($line, $column)]
);
}
}