Skip to content

Commit a4f6f93

Browse files
committed
Support load stages
1 parent d00ff43 commit a4f6f93

File tree

2 files changed

+124
-0
lines changed

2 files changed

+124
-0
lines changed

lib/Core/PipelineBuilder.php

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use PhpBench\Pipeline\Extension\Console\ConsoleExtension;
66
use Generator;
77
use PhpBench\Pipeline\Extension\Core\CoreExtension;
8+
use PhpBench\Pipeline\Core\Exception\InvalidStage;
89

910
final class PipelineBuilder
1011
{
@@ -47,6 +48,41 @@ public function build(): BuiltPipeline
4748
return new BuiltPipeline($this->stages, $generatorFactory);
4849
}
4950

51+
public function load(array $stages): self
52+
{
53+
foreach ($stages as $stage) {
54+
if (is_callable($stage) || is_string($stage)) {
55+
$this->stage($stage);
56+
continue;
57+
}
58+
59+
if (is_array($stage)) {
60+
switch (count($stage)) {
61+
case 1:
62+
list($stage) = $stage;
63+
$this->stage($stage);
64+
continue 2;
65+
case 2:
66+
list($stage, $config) = $stage;
67+
$this->stage($stage, $config);
68+
continue 2;
69+
default:
70+
throw new InvalidStage(sprintf(
71+
'Stage config element cannot have more than 2 elements, got %s',
72+
count($stage)
73+
));
74+
}
75+
}
76+
77+
throw new InvalidStage(sprintf(
78+
'Stage must either be an array config element or a callable, got "%s"',
79+
is_object($stage) ? get_class($stage) : gettype($stage)
80+
));
81+
}
82+
83+
return $this;
84+
}
85+
5086
/**
5187
* @var callable|Stage
5288
*/

tests/Unit/Core/PipelineBuilderTest.php

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
use PhpBench\Pipeline\Core\Stage;
1010
use Prophecy\Argument;
1111
use PhpBench\Pipeline\Core\Schema;
12+
use PhpBench\Pipeline\Core\Exception\InvalidStage;
13+
use stdClass;
1214

1315
class PipelineBuilderTest extends TestCase
1416
{
@@ -70,6 +72,92 @@ public function testBuildsPipelineWithStageAlias()
7072
$this->assertEquals(['Test'], $result);
7173
}
7274

75+
/**
76+
* @dataProvider provideBuildsPipelinesFromStages
77+
*/
78+
public function testBuildsPipelineFromStages(array $stages, array $expected, array $exception = [])
79+
{
80+
if ($exception) {
81+
list($class, $message) = $exception;
82+
$this->expectException($class);
83+
$this->expectExceptionMessage($message);
84+
}
85+
86+
$this->extension1->stageAliases()->willReturn(['test/foobar']);
87+
$this->extension1->stage('test/foobar')->willReturn($this->stage1->reveal());
88+
89+
$this->stage1->configure(Argument::type(Schema::class))->will(function ($args) {
90+
$schema = $args[0];
91+
$schema->setDefaults([ 'foo' => 'bar' ]);
92+
});
93+
$this->stage1->__invoke()->will(function () {
94+
yield;
95+
yield ['Test'];
96+
});
97+
98+
$builder = PipelineBuilder::create();
99+
$builder->addExtension($this->extension1->reveal());
100+
$builder->load($stages);
101+
102+
$pipeline = $builder->build();
103+
104+
$this->assertInstanceOf(BuiltPipeline::class, $pipeline);
105+
$result = $pipeline->run();
106+
$this->assertEquals($expected, $result);
107+
}
108+
109+
public function provideBuildsPipelinesFromStages()
110+
{
111+
yield 'with string alias' => [
112+
[
113+
'test/foobar'
114+
],
115+
[ 'Test' ],
116+
];
117+
yield 'with callable' => [
118+
[
119+
function () {
120+
yield;
121+
yield [ 'Hai!' ];
122+
},
123+
],
124+
[ 'Hai!' ],
125+
126+
];
127+
yield 'with alias in an array' => [
128+
[
129+
[ 'test/foobar' ]
130+
],
131+
[ 'Test' ],
132+
];
133+
yield 'with alias and config' => [
134+
[
135+
[ 'test/foobar', ['foo' => 'bar'] ]
136+
],
137+
[ 'Test' ],
138+
];
139+
yield 'but throws exception if stage has more than 2 elements ' => [
140+
[
141+
[ 'test/foobar', [], [] ]
142+
],
143+
[],
144+
[
145+
InvalidStage::class,
146+
'Stage config element cannot have more than 2 elements, got 3'
147+
]
148+
];
149+
yield 'but throws exception if stage was neither an array or a callable ' => [
150+
[
151+
new stdClass,
152+
],
153+
[],
154+
[
155+
InvalidStage::class,
156+
'Stage must either be an array config element or a callable, got "stdClass"'
157+
]
158+
];
159+
}
160+
73161
public function testBuildsPipelineWithMultipleStages()
74162
{
75163
$builder = PipelineBuilder::create();

0 commit comments

Comments
 (0)