-
Notifications
You must be signed in to change notification settings - Fork 266
PHPLIB-294: Make test suite compatible with PHPUnit 6.4 #489
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
Conversation
@@ -108,14 +110,34 @@ public function provideFileIdAndExpectedBytes() | |||
]; | |||
} | |||
|
|||
public function provideFilteredFileIdAndExpectedBytes() |
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 looks like there is no way to chain data providers so I thought this would be the most straightforward way to provide data to testReadBytesCalledMultipleTimes()
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.
If you want to avoid duplicating the datasets from provideFileIdAndExpectedBytes
, you could either call that data provider and run its return value through array_filter
. Altternatively, testReadBytesCalledMultipleTimes
could just skip all datasets that don't apply with markTestSkipped
. Not sure if any of those sound better to you, just providing some ideas.
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 looks like there is no way to chain data providers
Were you by chance reading about @depends
? That's the only form of test chaining I'm aware of, where the return value of one test can be used as input for a subsequent test case.
Anywho, I think I mentioned using array_filter()
earlier this week, which is exactly what @alcaeus is proposing here. Since provideFileIdAndExpectedBytes()
returns an array of argument arrays, and we just want to filter out any argument arrays where the length (i.e. second argument) is zero by using an anonymous function as our filter callback:
function(array $args) { return $args[1] > 0; }
Using provideFileIdAndExpectedBytes()
as the array_filter()
input, each of its 20 argument arrays will be run through our callback and only those where the callback returns true
will be kept. This allows us to re-use most of the existing data without duplicating it in the test sources.
@@ -27,6 +27,7 @@ public function testConstructorUpdateArgumentTypeCheck($update) | |||
|
|||
/** | |||
* @dataProvider provideUpdateDocuments | |||
* @doesNotPerformAssertions |
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.
TIL @doesNotPerformAssertions
is a thing.
Perhaps we can use this for the Bucket and WritableStream testValidConstructorOptions()
tests?
ReadableStream's testValidConstructorFileDocument()
test looks OK with the change you made in this PR (also because no other tests appear to call ReadableStream::getFile()
).
composer.json
Outdated
@@ -16,7 +16,7 @@ | |||
"ext-mongodb": "^1.4.0" | |||
}, | |||
"require-dev": { | |||
"phpunit/phpunit": "^4.8.36" | |||
"phpunit/phpunit": "^6.4" |
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 causes the 5.x jobs on Travis to fail, since there is no longer a compatible version of PHPUnit:
Problem 1
- phpunit/phpunit 6.5.6 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.5.5 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.5.4 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.5.3 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.5.2 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.5.1 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.5.0 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.4.4 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.4.3 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.4.2 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.4.1 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- phpunit/phpunit 6.4.0 requires php ^7.0 -> your PHP version (5.6.32) does not satisfy that requirement.
- Installation request for phpunit/phpunit ^6.4 -> satisfiable by phpunit/phpunit[6.4.0, 6.4.1, 6.4.2, 6.4.3, 6.4.4, 6.5.0, 6.5.1, 6.5.2, 6.5.3, 6.5.4, 6.5.5, 6.5.6].
I'd suggest using "^4.8.36 || ^6.4"
, which should support PHP 5.x while still allowing PHP 7 to use PHPUnit 6. That syntax is discussed in Version Range in the Composer docs.
tests/bootstrap.php
Outdated
@@ -9,3 +9,5 @@ | |||
} else { | |||
throw new Exception('Can\'t find autoload.php. Did you install dependencies with Composer?'); | |||
} | |||
|
|||
class_alias("PHPUnit\Framework\Error\Warning", "PHPUnit_Framework_Error_Warning"); |
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 is going to fail on PHPUnit 4 (PHP 5.x), as the original class (first argument) doesn't exist. You'll also get a warning because class_alias()
will try to autoload that class and fail to find it (controlled by its third boolean argument).
Instead, I'd suggest using the PHPUnit 6 class names in our tests and only creating the alias when needed for compatibility with PHPUnit 4:
if ( ! class_exists('PHPUnit\Framework\Error\Warning')) {
class_alias('PHPUnit_Framework_Error_Warning', 'PHPUnit\Framework\Error\Warning');
}
This condition should only be hit by PHPUnit 4, when the new class isn't found (even after an autoloading attempt). It will then create the PHPUnit\Framework\Error\Warning
alias for the old PHPUnit_Framework_Error_Warning
class, which will also be autoloaded by default.
AFAIK, the only references to "PHPUnit_Framework_Error_Warning" are in:
- tests/GridFS/BucketFunctionalTest.php
- tests/GridFS/SpecFunctionalTest.php
Most are in @expectedException
annotations but at least one is a string.
@@ -108,14 +110,34 @@ public function provideFileIdAndExpectedBytes() | |||
]; | |||
} | |||
|
|||
public function provideFilteredFileIdAndExpectedBytes() |
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 looks like there is no way to chain data providers
Were you by chance reading about @depends
? That's the only form of test chaining I'm aware of, where the return value of one test can be used as input for a subsequent test case.
Anywho, I think I mentioned using array_filter()
earlier this week, which is exactly what @alcaeus is proposing here. Since provideFileIdAndExpectedBytes()
returns an array of argument arrays, and we just want to filter out any argument arrays where the length (i.e. second argument) is zero by using an anonymous function as our filter callback:
function(array $args) { return $args[1] > 0; }
Using provideFileIdAndExpectedBytes()
as the array_filter()
input, each of its 20 argument arrays will be run through our callback and only those where the callback returns true
will be kept. This allows us to re-use most of the existing data without duplicating it in the test sources.
We're skipping PHPUnit 5 entirely and are keeping PHPUnit 4 compat, so I might also rephrase the commit and PR as:
|
@@ -17,6 +17,9 @@ | |||
*/ | |||
class BucketFunctionalTest extends FunctionalTestCase | |||
{ | |||
/* |
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 is missing a second *
in order to be considered a doc block. Without it, ReflectionFunction::getDocComment()
is not able to pick it up for parsing by PHPUnit.
return $args[1] > 0; | ||
} | ||
); | ||
return $filteredFiles; |
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 can be factored out so you simply return array_filter(...);
.
@@ -19,6 +19,9 @@ public function setUp() | |||
$this->collectionWrapper = new CollectionWrapper($this->manager, $this->getDatabaseName(), 'fs'); | |||
} | |||
|
|||
/* |
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.
Also needs another *
.
|
||
if ( ! class_exists('PHPUnit\Framework\Error\Warning')) { | ||
class_alias('PHPUnit_Framework_Error_Warning', 'PHPUnit\Framework\Error\Warning'); | ||
} |
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 ensures that any reference to PHPUnit\Framework\Error\Warning
will alias to PHPUnit_Framework_Error_Warning
, which doesn't currently affect anything. The GridFS tests still use PHPUnit_Framework_Error_Warning
, so they work for PHPUnit 4 but fail in 6.
See the renaming I suggested at the bottom of #489 (comment)
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.
Requesting a rename of one test. LGTM otherwise.
@@ -40,7 +40,9 @@ public function setUp() | |||
|
|||
public function testValidConstructorFileDocument() |
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.
Last minute request: can we change the test name to testGetFile()
?
https://jira.mongodb.org/browse/PHPLIB-294