Skip to content
Closed
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
8 changes: 8 additions & 0 deletions .claude/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,14 @@ Multiple service providers for optional features (auto-discovered via composer.j

Tests use `Tests\Utils\` namespace for test fixtures (Models, Queries, Mutations, etc.).

### GraphQL string style in tests

- Always annotate GraphQL literals with `/** @lang GraphQL */`.
- Default to nowdoc: `<<<'GRAPHQL'`.
- Use heredoc: `<<<GRAPHQL` only if interpolation is required.
- Avoid quoted multiline GraphQL strings.
- Preserve intentional indentation/whitespace in schema and assertion-sensitive tests.

## Code Style

- PHPStan level 8
Expand Down
10 changes: 10 additions & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,16 @@ $user = User::create([
]);
```

### GraphQL strings in tests

Use a consistent representation for GraphQL literals in tests:

- Use `/** @lang GraphQL */` before GraphQL string literals.
- Use nowdoc (`<<<'GRAPHQL'`) for static GraphQL content.
- Use heredoc (`<<<GRAPHQL`) only when interpolation is required.
- Prefer nowdoc/heredoc over quoted multiline strings.
- For schema/assertion cases where whitespace matters, keep indentation deliberate and stable.

## Working with proto files

Lighthouse uses [protobuf](https://developers.google.com/protocol-buffers) files for [federated tracing](src/Tracing/FederatedTracing/reports.proto).
Expand Down
10 changes: 5 additions & 5 deletions tests/Console/UnionDirective.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ final class UnionDirective extends BaseDirective implements Directive
public static function definition(): string
{
return /** @lang GraphQL */ <<<'GRAPHQL'
"""
Some other definition then the original.
"""
directive @union on UNION
GRAPHQL;
"""
Some other definition then the original.
"""
directive @union on UNION
GRAPHQL;
}
}
12 changes: 6 additions & 6 deletions tests/Console/ValidateSchemaCommandTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ final class ValidateSchemaCommandTest extends TestCase
{
public function testValidatesCorrectSchema(): void
{
$this->schema = /** @lang GraphQL */ '
$this->schema = /** @lang GraphQL */ <<<'GRAPHQL'
type Query {
foo(
arg: ID @eq
): ID @guard
}
';
GRAPHQL;
$tester = $this->commandTester(new ValidateSchemaCommand());
$tester->execute([]);

Expand All @@ -25,11 +25,11 @@ public function testValidatesCorrectSchema(): void

public function testFailsValidationUnknownDirective(): void
{
$this->schema = /** @lang GraphQL */ '
$this->schema = /** @lang GraphQL */ <<<'GRAPHQL'
type Query {
foo: ID @unknown
}
';
GRAPHQL;
$tester = $this->commandTester(new ValidateSchemaCommand());

$this->expectException(DirectiveException::class);
Expand All @@ -42,11 +42,11 @@ public function testFailsValidationDirectiveInWrongLocation(): void
$this->markTestSkipped('This validation needs to be in the upstream webonyx/graphql-php validation');

// @phpstan-ignore-next-line https://github.com/phpstan/phpstan-phpunit/issues/52
$this->schema = /** @lang GraphQL */ '
$this->schema = /** @lang GraphQL */ <<<'GRAPHQL'
type Query @field {
foo: ID @eq
}
';
GRAPHQL;
$tester = $this->commandTester(new ValidateSchemaCommand());
$tester->execute([]);

Expand Down
20 changes: 10 additions & 10 deletions tests/Integration/Async/AsyncDirectiveTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,18 @@ public function testDispatchesMutation(): void
{
$this->mockResolver(static fn (mixed $root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) => null);

$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */ <<<'GRAPHQL'
type Mutation {
fooAsync: Boolean! @mock @async
}
';
GRAPHQL;

$queue = Queue::fake();
$this->graphQL(/** @lang GraphQL */ '
$this->graphQL(/** @lang GraphQL */ <<<'GRAPHQL'
mutation {
fooAsync
}
')->assertExactJson([
GRAPHQL)->assertExactJson([
'data' => [
'fooAsync' => true,
],
Expand All @@ -48,18 +48,18 @@ public function testDispatchesMutationOnCustomQueue(): void
{
$this->mockResolver(static fn (mixed $root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo) => null);

$this->schema .= /** @lang GraphQL */ '
$this->schema .= /** @lang GraphQL */ <<<'GRAPHQL'
type Mutation {
fooAsync: Boolean! @mock @async(queue: "custom")
}
';
GRAPHQL;

$queue = Queue::fake();
$this->graphQL(/** @lang GraphQL */ '
$this->graphQL(/** @lang GraphQL */ <<<'GRAPHQL'
mutation {
fooAsync
}
')->assertExactJson([
GRAPHQL)->assertExactJson([
'data' => [
'fooAsync' => true,
],
Expand All @@ -82,10 +82,10 @@ public function testOnlyOnMutations(): void
$this->expectExceptionObject(new DefinitionException(
'The @async directive must only be used on root mutation fields, found it on Query.foo.',
));
$this->buildSchema(/** @lang GraphQL */ '
$this->buildSchema(/** @lang GraphQL */ <<<'GRAPHQL'
type Query {
foo: Boolean! @async
}
');
GRAPHQL);
}
}
Loading
Loading