Skip to content

Commit

Permalink
Merge pull request #3 from ergebnis/feature/concatenating-value-gener…
Browse files Browse the repository at this point in the history
…ator

Enhancement: Implement `ConcatenatingValueGenerator`
  • Loading branch information
localheinz authored Dec 30, 2023
2 parents d568c11 + f30bc61 commit 3a616a4
Show file tree
Hide file tree
Showing 7 changed files with 248 additions and 0 deletions.
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ For a full diff see [`f4208b3...main`][f4208b3...main].

- Added `ValueGenerator` ([#1]), by [@localheinz]
- Added `OptionalValueGenerator` ([#2]), by [@localheinz]
- Added `ConcatenatingValueGenerator` ([#3]), by [@localheinz]

[f4208b3...main]: https://github.com/ergebnis/data-generator/compare/f4208b3...main

[#1]: https://github.com/ergebnis/data-generator/pull/1
[#2]: https://github.com/ergebnis/data-generator/pull/2
[#3]: https://github.com/ergebnis/data-generator/pull/3

[@localheinz]: https://github.com/localheinz
37 changes: 37 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,46 @@ composer require ergebnis/data-generator

This project comes with the following data generators:

- [`Ergebnis\DataGenerator\ConcatenatingValueGenerator`](#ConcatenatingValuegenerator)
- [`Ergebnis\DataGenerator\OptionalValueGenerator`](#optionalvaluegenerator)
- [`Ergebnis\DataGenerator\ValueGenerator`](#valuegenerator)

### `ConcatenatingValueGenerator`

Use the `ConcatenatingValueGenerator` to generate values by concatenating values generated from one or more `StringGenerator`s:

```php
<?php

declare(strict_types=1);

use Ergebnis\DataGenerator;

$generator = new DataGenerator\ConcatenatingValueGenerator(
new DataGenerator\ValueGenerator(
'foo',
'bar',
'baz',
),
new DataGenerator\ValueGenerator('-'),
new DataGenerator\ValueGenerator(
'qux',
'quux',
),
);

foreach ($generator->generate() as $value) {
echo $value . PHP_EOL
}

// foo-qux
// foo-quux
// bar-qux
// bar-quux
// baz-qux
// baz-quux
```

### `OptionalValueGenerator`

Use the `OptionalValueGenerator` to generate an empty string and one or more values from a list of `string` values:
Expand Down
5 changes: 5 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.18.0@b113f3ed0259fd6e212d87c3df80eec95a6abf19">
<file src="test/Unit/ConcatenatingValueGeneratorTest.php">
<MixedArgument>
<code>$values</code>
</MixedArgument>
</file>
<file src="test/Unit/OptionalValueGeneratorTest.php">
<MixedArgument>
<code>$values</code>
Expand Down
51 changes: 51 additions & 0 deletions src/ConcatenatingValueGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/data-generator
*/

namespace Ergebnis\DataGenerator;

final class ConcatenatingValueGenerator implements StringGenerator
{
private readonly StringGenerator $firstGenerator;
private readonly StringGenerator $secondGenerator;

/**
* @throws Exception\InvalidGeneratorsException
*/
public function __construct(StringGenerator ...$generators)
{
$count = \count($generators);

if (0 === $count) {
throw Exception\InvalidGeneratorsException::empty();
}

$this->firstGenerator = \array_shift($generators);

if (1 === $count) {
$this->secondGenerator = new ValueGenerator('');

return;
}

$this->secondGenerator = new self(...$generators);
}

public function generate(): \Generator
{
foreach ($this->firstGenerator->generate() as $firstValue) {
foreach ($this->secondGenerator->generate() as $secondValue) {
yield $firstValue . $secondValue;
}
}
}
}
22 changes: 22 additions & 0 deletions src/Exception/InvalidGeneratorsException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/data-generator
*/

namespace Ergebnis\DataGenerator\Exception;

final class InvalidGeneratorsException extends \InvalidArgumentException
{
public static function empty(): self
{
return new self('Generators can not be empty.');
}
}
101 changes: 101 additions & 0 deletions test/Unit/ConcatenatingValueGeneratorTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/data-generator
*/

use Ergebnis\DataGenerator\ConcatenatingValueGenerator;
use Ergebnis\DataGenerator\Exception;
use Ergebnis\DataGenerator\Test;
use Ergebnis\DataGenerator\ValueGenerator;
use PHPUnit\Framework;

#[Framework\Attributes\CoversClass(ConcatenatingValueGenerator::class)]
#[Framework\Attributes\UsesClass(Exception\InvalidGeneratorsException::class)]
#[Framework\Attributes\UsesClass(ValueGenerator::class)]
final class ConcatenatingValueGeneratorTest extends Framework\TestCase
{
use Test\Util\Helper;

public function testConstructorRejectsEmptyGenerators(): void
{
$this->expectException(Exception\InvalidGeneratorsException::class);

new ConcatenatingValueGenerator();
}

public function testGenerateReturnsGeneratorThatYieldsValuesFromOneGenerator(): void
{
$values = self::faker()->words();

$generator = new ConcatenatingValueGenerator(new ValueGenerator(...$values));

$generated = \iterator_to_array($generator->generate());

self::assertSame($values, $generated);
}

public function testGenerateReturnsGeneratorThatYieldsValuesFromTwoGenerators(): void
{
$generator = new ConcatenatingValueGenerator(
new ValueGenerator(
'foo',
'bar',
),
new ValueGenerator(
'1',
'2',
'3',
),
);

$generated = \iterator_to_array($generator->generate());

$expected = [
'foo1',
'foo2',
'foo3',
'bar1',
'bar2',
'bar3',
];

self::assertSame($expected, $generated);
}

public function testGenerateReturnsGeneratorThatYieldsValuesFromThreeGenerators(): void
{
$generator = new ConcatenatingValueGenerator(
new ValueGenerator(
'foo',
'bar',
'baz',
),
new ValueGenerator('-'),
new ValueGenerator(
'qux',
'quux',
),
);

$generated = \iterator_to_array($generator->generate());

$expected = [
'foo-qux',
'foo-quux',
'bar-qux',
'bar-quux',
'baz-qux',
'baz-quux',
];

self::assertSame($expected, $generated);
}
}
30 changes: 30 additions & 0 deletions test/Unit/Exception/InvalidGeneratorsExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

/**
* Copyright (c) 2023 Andreas Möller
*
* For the full copyright and license information, please view
* the LICENSE.md file that was distributed with this source code.
*
* @see https://github.com/ergebnis/data-generator
*/

namespace Ergebnis\DataGenerator\Test\Unit\Exception;

use Ergebnis\DataGenerator\Exception;
use PHPUnit\Framework;

#[Framework\Attributes\CoversClass(Exception\InvalidGeneratorsException::class)]
final class InvalidGeneratorsExceptionTest extends Framework\TestCase
{
public function testEmptyReturnsException(): void
{
$exception = Exception\InvalidGeneratorsException::empty();

$message = 'Generators can not be empty.';

self::assertSame($message, $exception->getMessage());
}
}

0 comments on commit 3a616a4

Please sign in to comment.