Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 48 additions & 0 deletions examples/simple/expected/Operations/IncludeNonNullable.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
<?php

declare(strict_types=1);

namespace Spawnia\Sailor\Simple\Operations;

/**
* @extends \Spawnia\Sailor\Operation<\Spawnia\Sailor\Simple\Operations\IncludeNonNullable\IncludeNonNullableResult>
*/
class IncludeNonNullable extends \Spawnia\Sailor\Operation
{
/**
* @param bool $value
*/
public static function execute($value): IncludeNonNullable\IncludeNonNullableResult
{
return self::executeOperation(
$value,
);
}

protected static function converters(): array
{
static $converters;

return $converters ??= [

Check failure on line 26 in examples/simple/expected/Operations/IncludeNonNullable.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.3, highest)

Method Spawnia\Sailor\Simple\Operations\IncludeNonNullable::converters() should return array<int, array{string, Spawnia\Sailor\Convert\TypeConverter}> but returns mixed.

Check failure on line 26 in examples/simple/expected/Operations/IncludeNonNullable.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.4, highest)

Method Spawnia\Sailor\Simple\Operations\IncludeNonNullable::converters() should return array<int, array{string, Spawnia\Sailor\Convert\TypeConverter}> but returns mixed.

Check failure on line 26 in examples/simple/expected/Operations/IncludeNonNullable.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.5, highest)

Method Spawnia\Sailor\Simple\Operations\IncludeNonNullable::converters() should return array<int, array{string, Spawnia\Sailor\Convert\TypeConverter}> but returns mixed.

Check failure on line 26 in examples/simple/expected/Operations/IncludeNonNullable.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.2, highest)

Method Spawnia\Sailor\Simple\Operations\IncludeNonNullable::converters() should return array<int, array{string, Spawnia\Sailor\Convert\TypeConverter}> but returns mixed.
['value', new \Spawnia\Sailor\Convert\NonNullConverter(new \Spawnia\Sailor\Convert\BooleanConverter)],
];
}

public static function document(): string
{
return /* @lang GraphQL */ 'query IncludeNonNullable($value: Boolean!) {
__typename
nonNullable @include(if: $value)
}';
}

public static function endpoint(): string
{
return 'simple';
}

public static function config(): string
{
return \Safe\realpath(__DIR__ . '/../../sailor.php');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

declare(strict_types=1);

namespace Spawnia\Sailor\Simple\Operations\IncludeNonNullable;

/**
* @property string $nonNullable
* @property string $__typename
*/
class IncludeNonNullable extends \Spawnia\Sailor\ObjectLike
{
/**
* @param string $nonNullable
*/
public static function make($nonNullable): self
{
$instance = new self;

if ($nonNullable !== self::UNDEFINED) {
$instance->nonNullable = $nonNullable;
}
$instance->__typename = 'Query';

return $instance;
}

protected function converters(): array
{
static $converters;

return $converters ??= [

Check failure on line 32 in examples/simple/expected/Operations/IncludeNonNullable/IncludeNonNullable.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.3, highest)

Method Spawnia\Sailor\Simple\Operations\IncludeNonNullable\IncludeNonNullable::converters() should return array<string, Spawnia\Sailor\Convert\TypeConverter> but returns mixed.

Check failure on line 32 in examples/simple/expected/Operations/IncludeNonNullable/IncludeNonNullable.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.4, highest)

Method Spawnia\Sailor\Simple\Operations\IncludeNonNullable\IncludeNonNullable::converters() should return array<string, Spawnia\Sailor\Convert\TypeConverter> but returns mixed.

Check failure on line 32 in examples/simple/expected/Operations/IncludeNonNullable/IncludeNonNullable.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.5, highest)

Method Spawnia\Sailor\Simple\Operations\IncludeNonNullable\IncludeNonNullable::converters() should return array<string, Spawnia\Sailor\Convert\TypeConverter> but returns mixed.

Check failure on line 32 in examples/simple/expected/Operations/IncludeNonNullable/IncludeNonNullable.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.2, highest)

Method Spawnia\Sailor\Simple\Operations\IncludeNonNullable\IncludeNonNullable::converters() should return array<string, Spawnia\Sailor\Convert\TypeConverter> but returns mixed.
'nonNullable' => new \Spawnia\Sailor\Convert\NonNullConverter(new \Spawnia\Sailor\Convert\StringConverter),
'__typename' => new \Spawnia\Sailor\Convert\NonNullConverter(new \Spawnia\Sailor\Convert\StringConverter),
];
}

public static function endpoint(): string
{
return 'simple';
}

public static function config(): string
{
return \Safe\realpath(__DIR__ . '/../../../sailor.php');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace Spawnia\Sailor\Simple\Operations\IncludeNonNullable;

class IncludeNonNullableErrorFreeResult extends \Spawnia\Sailor\ErrorFreeResult
{
public IncludeNonNullable $data;

public static function endpoint(): string
{
return 'simple';
}

public static function config(): string
{
return \Safe\realpath(__DIR__ . '/../../../sailor.php');
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

namespace Spawnia\Sailor\Simple\Operations\IncludeNonNullable;

class IncludeNonNullableResult extends \Spawnia\Sailor\Result
{
public ?IncludeNonNullable $data = null;

protected function setData(\stdClass $data): void
{
$this->data = IncludeNonNullable::fromStdClass($data);
}

/**
* Useful for instantiation of successful mocked results.
*
* @return static
*/
public static function fromData(IncludeNonNullable $data): self
{
$instance = new static;
$instance->data = $data;

return $instance;
}

public function errorFree(): IncludeNonNullableErrorFreeResult
{
return IncludeNonNullableErrorFreeResult::fromResult($this);
}

public static function endpoint(): string
{
return 'simple';
}

public static function config(): string
{
return \Safe\realpath(__DIR__ . '/../../../sailor.php');
}
}
4 changes: 4 additions & 0 deletions examples/simple/src/clientDirectives.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,7 @@ query ClientDirectiveInlineFragmentQuery($value: Boolean!) {
query SkipNonNullable($value: Boolean!) {
nonNullable @skip(if: $value)
}

query IncludeNonNullable($value: Boolean!) {
nonNullable @include(if: $value)
}
160 changes: 157 additions & 3 deletions tests/Integration/SimpleTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
use Spawnia\Sailor\Response;
use Spawnia\Sailor\Simple\Operations\MyObjectNestedQuery;
use Spawnia\Sailor\Simple\Operations\MyScalarQuery;
use Spawnia\Sailor\Simple\Operations\SkipNonNullable\SkipNonNullable;
use Spawnia\Sailor\Simple\Operations\ClientDirectiveFragmentSpreadQuery;
use Spawnia\Sailor\Simple\Operations\ClientDirectiveInlineFragmentQuery;
use Spawnia\Sailor\Simple\Operations\ClientDirectiveQuery;
use Spawnia\Sailor\Simple\Operations\IncludeNonNullable;
use Spawnia\Sailor\Simple\Operations\SkipNonNullable;
use Spawnia\Sailor\Tests\TestCase;

final class SimpleTest extends TestCase
Expand Down Expand Up @@ -207,12 +211,162 @@
self::assertNull($object->nested);
}

public function testSkipNonNullable(): void
/** Server omits non-nullable field due to @skip directive. */
public function testSkipNonNullableFieldOmitted(): void
{
SkipNonNullable::fromStdClass((object) [
$result = SkipNonNullable\SkipNonNullable::fromStdClass((object) [
'__typename' => 'Query',
]);

self::assertNull($result->nonNullable);

Check failure on line 221 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 221 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.3, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 221 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.4, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 221 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (7.4, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 221 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.5, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 221 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.1, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 221 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.2, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.
}

/** Server returns non-nullable field despite @skip directive (skip condition was false). */
public function testSkipNonNullableFieldPresent(): void
{
$result = SkipNonNullable\SkipNonNullable::fromStdClass((object) [
'__typename' => 'Query',
'nonNullable' => 'value',
]);

self::assertSame('value', $result->nonNullable);
}

/** Server omits non-nullable field due to @include directive. */
public function testIncludeNonNullableFieldOmitted(): void
{
$result = IncludeNonNullable\IncludeNonNullable::fromStdClass((object) [
'__typename' => 'Query',
]);

self::assertNull($result->nonNullable);

Check failure on line 242 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 242 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.3, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 242 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.4, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 242 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (7.4, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 242 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.5, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 242 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.1, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 242 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.2, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.
}

/** Server returns non-nullable field because @include condition was true. */
public function testIncludeNonNullableFieldPresent(): void
{
$result = IncludeNonNullable\IncludeNonNullable::fromStdClass((object) [
'__typename' => 'Query',
'nonNullable' => 'value',
]);

self::assertSame('value', $result->nonNullable);
}

/** @skip on nullable field — field omitted from response. */
public function testSkipNullableFieldOmitted(): void
{
$result = ClientDirectiveQuery\ClientDirectiveQuery::fromStdClass((object) [
'__typename' => 'Query',
'twoArgs' => 'present',
]);

self::assertNull($result->scalarWithArg);
self::assertSame('present', $result->twoArgs);
}

/** @include on nullable field — field omitted from response. */
public function testIncludeNullableFieldOmitted(): void
{
$result = ClientDirectiveQuery\ClientDirectiveQuery::fromStdClass((object) [
'__typename' => 'Query',
'scalarWithArg' => 'present',
]);

self::assertNull($result->twoArgs);
self::assertSame('present', $result->scalarWithArg);
}

/** All directive-affected fields omitted simultaneously. */
public function testClientDirectiveAllFieldsOmitted(): void
{
$result = ClientDirectiveQuery\ClientDirectiveQuery::fromStdClass((object) [
'__typename' => 'Query',
]);

self::assertNull($result->scalarWithArg);
self::assertNull($result->twoArgs);
}

/** All fields present despite directives (conditions evaluated to keep fields). */
public function testClientDirectiveAllFieldsPresent(): void
{
$result = ClientDirectiveQuery\ClientDirectiveQuery::fromStdClass((object) [
'__typename' => 'Query',
'scalarWithArg' => 'foo',
'twoArgs' => 'bar',
]);

self::assertSame('foo', $result->scalarWithArg);
self::assertSame('bar', $result->twoArgs);
}

/** Fragment spread with @skip — fields from the fragment are omitted. */
public function testFragmentSpreadSkipOmitsField(): void
{
$result = ClientDirectiveFragmentSpreadQuery\ClientDirectiveFragmentSpreadQuery::fromStdClass((object) [
'__typename' => 'Query',
]);

self::assertNull($result->twoArgs);
}

/** Fragment spread with @skip — field present when skip condition is false. */
public function testFragmentSpreadSkipFieldPresent(): void
{
$result = ClientDirectiveFragmentSpreadQuery\ClientDirectiveFragmentSpreadQuery::fromStdClass((object) [
'__typename' => 'Query',
'twoArgs' => 'value',
]);

self::assertSame('value', $result->twoArgs);
}

/** Inline fragment with @skip — fields from the fragment are omitted. */
public function testInlineFragmentSkipOmitsField(): void
{
$result = ClientDirectiveInlineFragmentQuery\ClientDirectiveInlineFragmentQuery::fromStdClass((object) [
'__typename' => 'Query',
]);

self::assertNull($result->twoArgs);
}

/** Inline fragment with @skip — field present when skip condition is false. */
public function testInlineFragmentSkipFieldPresent(): void
{
$result = ClientDirectiveInlineFragmentQuery\ClientDirectiveInlineFragmentQuery::fromStdClass((object) [
'__typename' => 'Query',
'twoArgs' => 'value',
]);

self::assertSame('value', $result->twoArgs);
}

/** Via Result::fromStdClass with the full response envelope — field omitted. */
public function testSkipNonNullableViaResult(): void
{
$result = SkipNonNullable\SkipNonNullableResult::fromStdClass((object) [
'data' => (object) [
'__typename' => 'Query',
],
]);

self::assertNotNull($result->data);
self::assertNull($result->data->nonNullable);

Check failure on line 356 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 356 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.3, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 356 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.4, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 356 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (7.4, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 356 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.5, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 356 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.1, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.

Check failure on line 356 in tests/Integration/SimpleTest.php

View workflow job for this annotation

GitHub Actions / static-code-analysis (8.2, highest)

Call to static method PHPUnit\Framework\Assert::assertNull() with string will always evaluate to false.
}

/** Via Result::fromStdClass with the full response envelope — field present. */
public function testSkipNonNullableViaResultFieldPresent(): void
{
$result = SkipNonNullable\SkipNonNullableResult::fromStdClass((object) [
'data' => (object) [
'__typename' => 'Query',
'nonNullable' => 'hello',
],
]);

self::assertNotNull($result->data);
self::assertSame('hello', $result->data->nonNullable);
}
}
Loading