Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introduce reusable test utility dedent() #936

Closed
wants to merge 2 commits into from
Closed

Conversation

vhenzl
Copy link
Contributor

@vhenzl vhenzl commented Sep 12, 2021

Equivalent of dedent() test utility function from graphql-js.

Its behaviour matches graphql-js v15 (v16 version trims trailing newlines).

Introduced in reaction to #930 (review)

It lives in tests/TestUtils directory, where I later intend to move other testing utilities and fixtures (similarly to graphql-js's __testUtils__).

Personally, I would prefer to have the utility as a function, rather than a static method. But that wouldn't quite fit into the current codebase.

Compare these two snippets:

$sdl = TestUtils::dedent('
    type Query {
      field(in: Input): String
    }
');
$sdl = dedent('
    type Query {
      field(in: Input): String
    }
');

TestUtils:: is completely unnecessary noise that doesn't add any additional information about dedent(). And it also further complicates already difficult diffing with graphql-js.

To keep the code consistent with the current "static methods for everything" approach, I went with Str::dedent(). It's at least short and has the meaning of "dedent is a function operating on a string".

However, if you would like to give it a go, I'm happy to refactor the method to a function. There are more static methods that could be changed to functions and I believe the codebase could benefit from it.

@codecov
Copy link

codecov bot commented Sep 12, 2021

Codecov Report

Merging #936 (8d5e06c) into master (b85f8a0) will increase coverage by 0.05%.
The diff coverage is n/a.

Impacted file tree graph

@@             Coverage Diff              @@
##             master     #936      +/-   ##
============================================
+ Coverage     94.18%   94.23%   +0.05%     
  Complexity       50       50              
============================================
  Files           117      117              
  Lines          9659     9679      +20     
============================================
+ Hits           9097     9121      +24     
+ Misses          562      558       -4     
Impacted Files Coverage Δ
src/Language/Lexer.php 97.75% <0.00%> (ø)
src/Utils/ASTDefinitionBuilder.php 90.00% <0.00%> (ø)
src/Utils/BlockString.php
src/Language/BlockString.php 100.00% <0.00%> (ø)
src/Utils/Utils.php 83.02% <0.00%> (+1.83%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update b85f8a0...8d5e06c. Read the comment docs.

@spawnia
Copy link
Collaborator

spawnia commented Sep 13, 2021

We can have a discussion about using functions over static methods in an issue, separate from this pull request. Last time I checked, they were suboptimal for performance when compared with autoloading.

tests/TestUtils/Str.php Outdated Show resolved Hide resolved
}
');
self::assertEquals(
implode(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be easier to use a NOWDOC?

Copy link
Contributor Author

@vhenzl vhenzl Sep 13, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was thinking about it for a short moment myself, but I dismissed the idea. I'm trying to keep the code generally and tests particularly as much close to the reference implementation as possible to make it easy to reflect future changes.

dedent() deals with whitespaces and empty lines, so it's important to be clear about what the testing string is. I believe using implode() is more explicit than NOWDOC where is easier to get lost in the indentation etc. It also makes changes like this one super obvious: graphql/graphql-js@1e46389#diff-6738ab51d9c26ea2d4b271f22bb521b267a1e290755dc4cf5da78fcf86facb6c

Co-authored-by: Benedikt Franke <[email protected]>
@vhenzl
Copy link
Contributor Author

vhenzl commented Sep 14, 2021

@spawnia, your comment (#936 (comment)) made me think if we actually need dedent() at all and if nowdoc/heredoc with indentation wouldn't be enough. Probably would. In some way, it's actually closer to the tagged template dedent``.

One disadvantage I can see is that nowdoc ignores the last newline, so it needs an extra one to get the same behaviour:

$sdl = <<<'GQL'
    type Query {
      field(in: Input): String
    }

    GQL;

Another disadvantage is that nowdoc is a language construct and we can't control its behaviour as we could with dedent(). So the change like graphql/graphql-js@1e46389 would require us to modify all nowdoc occurrences in all tests instead of changing only dedent()'s implementation.

@vhenzl
Copy link
Contributor Author

vhenzl commented Sep 17, 2021

@spawnia, have a look at #941. I have used nowdoc there and it looks fine. If you are happy with it, we can close this PR.

@spawnia spawnia closed this Sep 30, 2021
@vhenzl vhenzl deleted the dedent branch October 1, 2021 07:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants