Skip to content

Commit

Permalink
fix(graphql): Test assertions should work event when `LIGHTHOUSE_CACH…
Browse files Browse the repository at this point in the history
…E_ENABLE=true`.

Closes: #43
  • Loading branch information
LastDragon-ru committed Dec 10, 2022
1 parent 7ff3ba0 commit e5a2129
Show file tree
Hide file tree
Showing 6 changed files with 199 additions and 32 deletions.
57 changes: 37 additions & 20 deletions packages/graphql/src/Testing/GraphQLAssertions.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,7 @@

use GraphQL\Type\Definition\Type;
use GraphQL\Type\Schema;
use Illuminate\Contracts\Config\Repository;
use LastDragon_ru\LaraASP\Core\Utils\Cast;
use Illuminate\Contracts\Container\Container;
use LastDragon_ru\LaraASP\GraphQL\SchemaPrinter\Contracts\PrintedSchema;
use LastDragon_ru\LaraASP\GraphQL\SchemaPrinter\Contracts\PrintedType;
use LastDragon_ru\LaraASP\GraphQL\SchemaPrinter\Contracts\SchemaPrinter;
Expand All @@ -14,14 +13,13 @@
use LastDragon_ru\LaraASP\GraphQL\Testing\Package\SchemaPrinter\TestSettings;
use LastDragon_ru\LaraASP\Testing\Utils\Args;
use Nuwave\Lighthouse\Schema\SchemaBuilder;
use Nuwave\Lighthouse\Schema\Source\SchemaSourceProvider;
use Nuwave\Lighthouse\Schema\Source\SchemaStitcher;
use Nuwave\Lighthouse\Testing\MocksResolvers;
use Nuwave\Lighthouse\Testing\TestSchemaProvider;
use PHPUnit\Framework\TestCase;
use SplFileInfo;

use function array_combine;
use function assert;
use function is_string;

/**
Expand Down Expand Up @@ -218,32 +216,27 @@ protected function useGraphQLSchema(SplFileInfo|string $schema): static {
$schema = Args::content($schema);
$provider = new TestSchemaProvider($schema);

$this->instance(SchemaSourceProvider::class, $provider);
$this->getGraphQLSchemaBuilder()->setSchema($provider);

return $this;
}

protected function getGraphQLSchema(SplFileInfo|string $schema): Schema {
$this->useGraphQLSchema($schema);
try {
return $this->useGraphQLSchema($schema)->getGraphQLSchemaBuilder()->schema();
} finally {
$this->useDefaultGraphQLSchema();
}
}

$graphql = $this->app->make(SchemaBuilder::class);
$schema = $graphql->schema();
protected function useDefaultGraphQLSchema(): static {
$this->getGraphQLSchemaBuilder()->setSchema(null);

return $schema;
return $this;
}

protected function getDefaultGraphQLSchema(): Schema {
$this->instance(
SchemaSourceProvider::class,
new SchemaStitcher(
Cast::toString($this->app->make(Repository::class)->get('lighthouse.schema.register', '')),
),
);

$graphql = $this->app->make(SchemaBuilder::class);
$schema = $graphql->schema();

return $schema;
return $this->useDefaultGraphQLSchema()->getGraphQLSchemaBuilder()->schema();
}

protected function printGraphQLSchema(
Expand Down Expand Up @@ -284,5 +277,29 @@ protected function printGraphQLType(PrintedType|Type $type, Settings $settings =
protected function getGraphQLSchemaPrinter(Settings $settings = null): SchemaPrinter {
return $this->app->make(SchemaPrinter::class)->setSettings($settings ?? new TestSettings());
}

protected function getGraphQLSchemaBuilder(): SchemaBuilderWrapper {
// Wrap
$builder = $this->app->resolved(SchemaBuilder::class)
? $this->app->make(SchemaBuilder::class)
: null;

if (!($builder instanceof SchemaBuilderWrapper)) {
$this->app->extend(
SchemaBuilder::class,
static function (SchemaBuilder $builder, Container $container): SchemaBuilder {
return new SchemaBuilderWrapper($container, $builder);
},
);
}

// Instance
$builder = $this->app->make(SchemaBuilder::class);

assert($builder instanceof SchemaBuilderWrapper);

// Return
return $builder;
}
// </editor-fold>
}
19 changes: 19 additions & 0 deletions packages/graphql/src/Testing/Package/Provider.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php declare(strict_types = 1);

namespace LastDragon_ru\LaraASP\GraphQL\Testing\Package;

use Illuminate\Contracts\Config\Repository;
use Illuminate\Support\ServiceProvider;

class Provider extends ServiceProvider {
public function register(): void {
parent::register();

$this->callAfterResolving(
Repository::class,
static function (Repository $config): void {
$config->set('lighthouse.schema.register', __DIR__.'/schema.graphql');
},
);
}
}
30 changes: 18 additions & 12 deletions packages/graphql/src/Testing/Package/TestCase.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use LastDragon_ru\LaraASP\GraphQL\SchemaPrinter\Contracts\SchemaPrinter;
use LastDragon_ru\LaraASP\GraphQL\SchemaPrinter\Contracts\Settings;
use LastDragon_ru\LaraASP\GraphQL\Testing\GraphQLAssertions;
use LastDragon_ru\LaraASP\GraphQL\Testing\Package\Provider as TestProvider;
use LastDragon_ru\LaraASP\GraphQL\Testing\Package\SchemaPrinter\LighthouseDirectiveFilter;
use LastDragon_ru\LaraASP\GraphQL\Testing\Package\SchemaPrinter\TestSettings;
use LastDragon_ru\LaraASP\GraphQL\Utils\ArgumentFactory;
Expand All @@ -24,6 +25,7 @@ class TestCase extends PackageTestCase {
protected function getPackageProviders(mixed $app): array {
return [
Provider::class,
TestProvider::class,
LighthouseServiceProvider::class,
];
}
Expand All @@ -39,17 +41,21 @@ protected function getGraphQLSchemaPrinter(Settings $settings = null): SchemaPri
}

protected function getGraphQLArgument(string $type, mixed $value, SplFileInfo|string $schema = null): Argument {
$this->useGraphQLSchema(
$schema ?? <<<'GRAPHQL'
type Query {
test: Int @all
}
GRAPHQL,
);

$factory = $this->app->make(ArgumentFactory::class);
$argument = $factory->getArgument($type, $value);

return $argument;
try {
$this->useGraphQLSchema(
$schema ?? <<<'GRAPHQL'
type Query {
test: Int @all
}
GRAPHQL,
);

$factory = $this->app->make(ArgumentFactory::class);
$argument = $factory->getArgument($type, $value);

return $argument;
} finally {
$this->useDefaultGraphQLSchema();
}
}
}
3 changes: 3 additions & 0 deletions packages/graphql/src/Testing/Package/schema.graphql
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
type Query {
test: String!
}
84 changes: 84 additions & 0 deletions packages/graphql/src/Testing/SchemaBuilderWrapper.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<?php declare(strict_types = 1);

namespace LastDragon_ru\LaraASP\GraphQL\Testing;

use GraphQL\Type\Schema;
use Illuminate\Config\Repository;
use Illuminate\Contracts\Config\Repository as ConfigContract;
use Illuminate\Contracts\Container\Container;
use Illuminate\Contracts\Events\Dispatcher as EventsDispatcher;
use Illuminate\Support\Arr;
use Nuwave\Lighthouse\Schema\AST\ASTBuilder;
use Nuwave\Lighthouse\Schema\AST\ASTCache;
use Nuwave\Lighthouse\Schema\DirectiveLocator;
use Nuwave\Lighthouse\Schema\SchemaBuilder;
use Nuwave\Lighthouse\Schema\Source\SchemaSourceProvider;
use Nuwave\Lighthouse\Schema\TypeRegistry;

use function spl_object_hash;

class SchemaBuilderWrapper extends SchemaBuilder {
protected ?SchemaBuilder $current = null;

/**
* @var array<class-string, object>
*/
protected array $singletons = [];

/**
* @noinspection PhpMissingParentConstructorInspection
* @phpstan-ignore-next-line no need to call parent `__construct`
*/
public function __construct(
protected Container $container,
protected SchemaBuilder $builder,
) {
// no need to call parent
}

protected function getSchemaBuilder(): SchemaBuilder {
return $this->current ?? $this->builder;
}

public function schema(): Schema {
return $this->getSchemaBuilder()->schema();
}

public function setSchema(?SchemaSourceProvider $provider): void {
// Origins
if (!$this->singletons) {
$this->singletons = [
ASTCache::class => $this->container->make(ASTCache::class),
ASTBuilder::class => $this->container->make(ASTBuilder::class),
];
}

// Build
$builder = null;

if ($provider) {
$config = $this->container->make(ConfigContract::class)->all();

Arr::set($config, 'lighthouse.cache.key', spl_object_hash($provider));
Arr::set($config, 'lighthouse.cache.enable', true);
Arr::set($config, 'lighthouse.cache.version', 1); // cache

$types = $this->container->make(TypeRegistry::class);
$dispatcher = $this->container->make(EventsDispatcher::class);
$directives = $this->container->make(DirectiveLocator::class);
$astCache = new ASTCache(new Repository($config));
$astBuilder = new ASTBuilder($directives, $provider, $dispatcher, $astCache);
$builder = new SchemaBuilder($types, $astBuilder);

$this->container->instance(ASTCache::class, $astCache);
$this->container->instance(ASTBuilder::class, $astBuilder);
} else {
foreach ($this->singletons as $abstract => $instance) {
$this->container->instance($abstract, $instance);
}
}

// Set
$this->current = $builder;
}
}
38 changes: 38 additions & 0 deletions packages/graphql/src/Testing/SchemaBuilderWrapperTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php declare(strict_types = 1);

namespace LastDragon_ru\LaraASP\GraphQL\Testing;

use LastDragon_ru\LaraASP\GraphQL\Testing\Package\TestCase;
use Nuwave\Lighthouse\Schema\SchemaBuilder;
use ReflectionClass;
use ReflectionMethod;

/**
* @internal
* @coversDefaultClass \LastDragon_ru\LaraASP\GraphQL\Testing\SchemaBuilderWrapper
*/
class SchemaBuilderWrapperTest extends TestCase {
/**
* @covers ::__construct
*/
public function testWrappedSuccessfully(): void {
$missed = [];
$origin = new ReflectionClass(SchemaBuilder::class);
$methods = $origin->getMethods(ReflectionMethod::IS_PUBLIC);
$wrapper = new ReflectionClass(SchemaBuilderWrapper::class);

foreach ($methods as $method) {
if ($method->isConstructor()) {
continue;
}

$wrapped = $wrapper->getMethod($method->name);

if ($wrapped->getDeclaringClass()->getName() !== $wrapper->getName()) {
$missed[] = $method->name;
}
}

self::assertEquals([], $missed, 'Some methods are not wrapped.');
}
}

0 comments on commit e5a2129

Please sign in to comment.