-
Notifications
You must be signed in to change notification settings - Fork 23
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
Tests, tests, and more tests #45
Conversation
TODO: |
Very nice job! What's with the uppercase variables, though? ;) |
Ah. Not terribly important/necessary, I tend to prefer using pascal case for objects and collections of objects atm ;) Only bothered adjusting as I was poking around in that file anyway. |
tests/HeaderFactoryTest.php
Outdated
foreach ($Headers as $Header) | ||
{ | ||
$this->assertSame( | ||
'Aidantwoods\SecureHeaders\Headers\CSPHeader', |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's an assert just for this to skip the extra get_class
: https://phpunit.de/manual/current/en/appendixes.assertions.html#appendixes.assertions.assertInstanceOf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for taking a look!
I had a look at that, I figured it worked like PHP's instanceof
though? (which isn't what I want – interested in the exact class).
Would work okay for CSPHeader
right now, but not for RegularHeader
(as CSPHeader
extends RegularHeader
– so any CSPHeader
is an instanceof
RegularHeader
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thinking about that now, not sure if it would make sense to refactor RegularHeader
's contents into an abstract base so we can have method sharing while having separate instanceable types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
} | ||
else | ||
{ | ||
$this->assertEquals($expectedErrors, $Errors); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure assertEquals
is sufficient to test arrays of Error
, other than that their counts are equal. This is the code that generates the string being compared for each element: https://github.com/sebastianbergmann/exporter/blob/master/src/Exporter.php#L122 So that will be doing something like
if ("Error Object (n)" !== "Error Object (n)") throw("unequal");
So this might need a manual cycle through the array checking the toString
of the object.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good enough for me. I must have misread the maze of repos inside phpunit.
"default-src 'unsafe-inline' 'unsafe-eval'; " | ||
. "script-src 'unsafe-inline' 'unsafe-eval'", | ||
[ | ||
new Error( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It would help the provider's readability to declare each type of error to-be-checked once at the top of this file. Also serves the usual DRY spiel.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hehe, yea. All errors are subtly different in their error message (so would have to replicate one of the functions from src
to help condense the code enough to generate the messages on the fly)... feels a little weird replicating a method in a test that is one of the methods being tested, but probably okay in this case though.
Cheers for this detailed review :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, ok. I feel you about not making the test so complicated that needs its own tests. Readability is king is my usual litmus test. Maybe subtype the errors in order to validate that the right list of types is generated, but then test the string output of each subtype in its own test? That's probably overkill, too.
Good luck with the release.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Readability is king is my usual litmus test. Maybe subtype the errors in order to validate that the right list of types is generated, but then test the string output of each subtype in its own test? That's probably overkill, too.
It's certainly sometimes difficult to balance the simplicity with DRY.
IMO DRY works quite well for the actual code base, for tests, the most important thing is to be able to see easily see what's going on (preferably within one file, or method even).
I'll have a ponder about best way to balance this, kinda thinking it may be easiest, and most readable, to just reimplement this string substitution as a method in the test file.
Maybe I'll push doing that to after release though, more of an aesthetics thing, so won't change any actual test results. (happy to merge a PR doing that though 😉)
Good luck with the release.
Thank you! 🎉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This might be a good place to use named constructors instead of reimplementing the method under test in the test. :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd have to modify the error class every time we introduced a new error message? Maybe I'm misunderstanding what you're suggesting?
I was thinking something like:
$Error = CSPBadFlags::createBadFlagError($friendlyHeader, $badFlag, $attributeName);
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since it's just about the error message, IMO the method would belong on the Error class.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We'd have to modify the Error
class for each new error message? Seems to go against the responsability of the class IMO (since specifics of the message are to do with the thing that creates it)?
Something like:
$Error = Error::createBadFlagError($friendlyHeader, $badFlag, $attributeName);
?
Perhaps Error
subtypes might be more fitting?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's something to decide when new error messages come around.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
c10499c
to
1f4f1a4
Compare
Happy to accept tests via PRs, I think that's me finished for now though!
|
Closes #39
I've wrapped in a couple bugfixes I patched while writing the tests 😉
Implicitly:
Closes #3
Closes #27