rawr / cross-data-providers
Lightweight builder for PhpUnit data providers
Installs: 381 042
Dependents: 4
Suggesters: 0
Security: 0
Stars: 32
Watchers: 2
Forks: 6
pkg:composer/rawr/cross-data-providers
Requires
- php: >=7.1.0
Requires (Dev)
- phpunit/phpunit: ^9.5.4 || ^8.0 || ^7.5
This package is auto-updated.
Last update: 2023-08-07 18:48:13 UTC
README
Helper for PhpUnit @dataProvider
Handy require-dev testing tool for PhpUnit. It allows to manage data providers
with zip(), join(), cross(), pairs(), slice() and more.
Installation
Installation for PHP 7.1 and later:
composer require --dev rawr/phpunit-data-provider
Overview
DataProvider can be used to build, compose and edit data providers to be used with PhpUnit
by @sebastianbergmann.
DataProvider::list()
DataProvider::list() provides a list of elements. Test is invoked each time with a single argument.
/** * @test * @dataProvider colors */ public function test(string $color): void { // your test here } public function colors(): DataProvider { return DataProvider::list("blue", "yellow", "red"); }
Additionally, DataProvider::list() names rows based on values.
DataProvider::join()
Vertically join data providers together.
💡 Useful when two data providers are used in other tests, and a new test should use both of them.
/** * @test * @dataProvider colors */ public function test(string $color, string $thing): void { // your test here } public function colors(): DataProvider { return DataProvider::join($this->natureColors(), $this->shadeColors()); } public function natureColors(): DataProvider { return DataProvider::sets( ["blue", "sky"], ["yellow", "sun"], ["red", "apple"] ); } public function shadeColors(): array { return [ 'hair' => ["gray", "hair"], 'ink' => ["black", "ink"], 'dust' => ["lightgray", "dust"] ]; }
DataProvider::zip()
Horizontally join data providers together.
💡 Useful for keeping data providers clean and simple.
/** * @test * @dataProvider colors */ public function test($blueColor, $blueThing, $yellowThing, $redThing): void { // your test here } public function colors(): DataProvider { return DataProvider::zip($this->blueThings(), $this->yellowThings(), $this->redThings()); } public function blueThings(): DataProvider { return DataProvider::sets( ["blue", "pen"], ["light blue", "shirt"], ["deep blue", "ocean"] ); } public function yellowThings(): iterable { return DataProvider::list("sun", "apple", "lemon"); } public function redThings(): iterable { yield ["apple"]; yield ["cranberry"]; yield ["car"]; }
DataProvider::cross()
Creates a square matrix of given data providers.
💡 Useful for testing all combinations of arguments.
/** * @test * @dataProvider shadedColors */ public function test(string $shade, string $color): void { // your test here } public function shadedColors(): DataProvider { return DataProvider::cross($this->shades(), $this->colors()); } public function shades(): iterable { return DataProvider::list("light", "standard", "dark"); } public function colors(): array { return [ ["blue"], ["yellow"], ["red"] ]; }
DataProvider::pairs()
Calls test with two arguments. Each argument is paired with all of the other arguments.
Example shows a test paring image formats:
/** * @test * @dataProvider formats */ public function shouldConvertFile(string $from, string $to): void { // your test here } public function formats(): array { return DataProviders::distinctPairs('png', 'jpg', 'bmp'); }
DataProvider::of()
Instantiates a DataProvider from a raw-array accepted by PhpUnit.
public function example(): DataProvider { return DataProvider::of($this->rawArray()); } public function rawArrayDataProvider(): array { return [ 'key' => ['argument 1', 'argument 2'] ]; }
DataProvider::sets()
Provide multiple arguments for each a test. DataProvider::sets() names each row based on the values.
/** * @test * @dataProvider colors */ public function test(string color, string $thing): void { // your test here } public function colors(): DataProvider { return DataProvider::sets( ["blue", "sky"], ["yellow", "sun"], ["red", "apple"] ); }
DataProvider::dictionary()
Specify a single argument for test. DataProvider::dictionary() names each row based on the provided array key.
/** * @test * @dataProvider colors */ public function test(string color): void { // your test here } public function colors(): DataProvider { return DataProvider::dictionary([ "custom key 1" => "blue", "custom key 2" => "yellow", "custom key 3" => "red" ]); }
In most cases, DataProvider::list() should probably be used over DataProvider::dictionary(). Method ::dictionary()
is useful when the arguments are not self-explanatory, for example:
public function ports(): DataProvider { return DataProvider::dictionary([ "http" => 80, "https" => 443, "ftp" => 21 ]); }
Documentation
Features
DataProvideraccepts many provider types.- each builder method sets proper names for rows, based on values
- properly handled duplicates in keys, formatting them in an informative manner
- lazily evaluates iterators, calling them only once (even if the provider is used multiple times)
Functionalities
Creating new data providers:
DataProvider::list(),DataProvider::sets(),DataProvider::dictionary(),DataProvider::pairs(),DataProvider::distinctPairs()
Composing existing providers:
DataProvider::zip(),DataProvider::join(),DataProvider::cross(),DataProvider::of()
Editing existing providers:
DataProvider.slice(),DataProvider.drop()
Names
DataProvider sets proper names for each row based on values.
/** * @test * @dataProvider colors */ public function test(string color, string $thing): void { // your test here } public function colors(): DataProvider { return DataProvider::sets( ["blue", "sky"], ["yellow", "sun"], ["red", "apple"] ); }
Documentation
Example usage
DataProvider::cross() returns an instance of DataProvider which is a square matrix of input data providers.
/** * @test * @dataProvider services */ public function shouldLogin(string $service, string $method, int $port): void { // your test here } public function services(): DataProvider { return DataProvider::cross( [ ['github.com'], ['bitbucket.com'], ['gitlab.com'], ['sourceforge.net'] ], [ ['http', 80], ['https', 443], ['ssh', 22] ]); }
This is equivalent of having a regular data provider that is composed of 12 entries, that look like this:
public function services(): array { return [ ['github.com', 'http', 80], ['github.com', 'https', 443], ['github.com', 'ssh', 22], ['bitbucket.com', 'http', 80], ['bitbucket.com', 'https', 443], ['bitbucket.com', 'ssh', 22], ['gitlab.com', 'http', 80], ['gitlab.com', 'https', 443], ['gitlab.com', 'ssh', 22], ['sourceforge.net', 'http', 80], ['sourceforge.net', 'https', 443], ['sourceforge.net', 'ssh', 22], ]; }
DataProvider::cross() accepts data providers of different
types: array, \Iterator, \IteratorAggregate, \Traversable, \Generator,
iterable and DataProvider.
That means DataProvider can be composed together.
public function services(): DataProvider { return DataProvider::cross( DataProvider::list('github.com', 'bitbucket.com', 'gitlab.com', 'sourceforge.net'), DataProvider::sets(['http', 80], ['https', 443], ['ssh', 22])); }
Advanced usage
DataProvider can be combined with other DataProviders as well as regular PhpUnit data providers.
/** * @test * @dataProvider urls */ public function test0(string $url): void { // your test here } /** * @test * @dataProvider services */ public function test1(string $url, string $name, string $method, int $port): void { // your test here } /** * @test * @dataProvider allServices */ public function test2(string $url, string $name, string $method, int $port): void { // your test here } public function urls(): DataProvider { return DataProvider::list('github.com', 'bitbucket.com', 'gitlab.com', 'sourceforge.net'); } public function rawArrayProvider(): array { return [ ['GitHub'], ['BitBucket'], ['GitLab'], ['SourceForge'] ]; } public function services(): DataProvider { return DataProvider::cross( DataProvider::zip($this->urls(), $this->rawArrayProvider()), DataProvider::sets( ['http', 80], ['https', 443], ['ssh', 22])); } public function allServices(): DataProvider { return DataProvider::join( $this->services(), $this->localServices() ); } public function localServices(): array { return [ 'my local service' => ['localhost', 'local', 'http', '80'] ]; }
Accepted types
DataProvider accepts any type of data provider:
- all types allowed
by PhpUnit:
array,iterable,\Traversable,\Iterator,\IteratorAggregate,\Generator DataProvideritself
Notes
Notes on DataProvider::join():
DataProvider::join()preserves names of each data provider, and also joins the names vertically. Duplicates in titles are preserved and presented appropriately.DataProvider::join()accepts any type of data-provider.DataProvider::join()is conceptually similar to calling\array_merge()on raw-array providers, but\array_merge()would override duplicate keys, whileDataProvider::join()preserves duplicate keys, and titles them appropriately.DataProvider::join()variadic arguments...iterableand can be used to join many data providersDataProvider::join()can only join data providers with the same amount of arguments in each row, otherwiseIrregularDataProviderExceptionis thrown.DataProvider::join()acceptsDataProvideror otheriterableaccepted by PhpUnit. If improper data-provider is passed,MalformedDataProviderExceptionis thrown.
Notes on DataProvider::zip():
DataProvider::zip()preserves names of each data provider, and also joins them horizontally.DataProvider::zip()accepts any type of data-provider.DataProvider::zip()variadic arguments...iterableand can zip many data providersDataProvider::zip()can only zip data providers with the same amount of rows, otherwiseIrregularDataProviderExceptionis thrown. Additionally, each particular data provider must have the same amount of arguments in each row.DataProvider::zip()acceptsDataProvideror otheriterableaccepted by PhpUnit. If improper data-provider is passed,MalformedDataProviderExceptionis thrown.
Note on DataProvider::pairs():
DataProvider::pairs()produces duplicate pairs (for example'png', 'png'), whileDataProvider::distinctPairs()only makes pairs of different arguments.
Note on DataProvider::sets():
DataProvider::sets()is similar toDataProvider::of(), but::of()accepts an explicit name, whileDataProvider::sets()titles the rows according to the values in the sets.
Migration from previous version
To use version 3.0.0, migrating from 2.4.0 or earlier:
- Library namespace changed from
\TRegx\DataProvider\to\TRegx\PhpUnit\DataProviders\. - Change
\TRegx\DataProvider\DataProviders::cross()to\TRegx\PhpUnit\DataProviders\DataProvider::cross(). - Change
\TRegx\DataProvider\CrossDataProviders::cross()to\TRegx\PhpUnit\DataProviders\DataProvider::cross(). - Change your data providers return type from
arraytoiterableor\TRegx\PhpUnit\DataProviders\DataProvider. - Removed
\TRegx\DataProvider\CrossDataProviders::builder(), use\TRegx\PhpUnit\DataProviders\DataProvider::cross()instead.









