Skip to content

Commit c143bec

Browse files
committed
Multi request support for cli run
1 parent ba5b792 commit c143bec

File tree

2 files changed

+64
-38
lines changed

2 files changed

+64
-38
lines changed

src/ExerciseRunner/CliRunner.php

Lines changed: 48 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -131,26 +131,35 @@ private function getPhpProcess($fileName, ArrayObject $args)
131131
public function verify(Input $input)
132132
{
133133
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.verify.start', $this->exercise, $input));
134-
//BC - getArgs only returned 1 set of args in v1 instead of multiple sets of args in v2
135-
$args = $this->exercise->getArgs();
136-
if (isset($args[0]) && !is_array($args[0])) {
137-
$args = [$args];
138-
} elseif (empty($args)) {
139-
$args = [[]];
140-
}
141-
//END BC
142134
$result = new CliResult(
143135
array_map(
144136
function (array $args) use ($input) {
145137
return $this->doVerify($args, $input);
146138
},
147-
$args
139+
$this->preserveOldArgFormat($this->exercise->getArgs())
148140
)
149141
);
150142
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.verify.finish', $this->exercise, $input));
151143
return $result;
152144
}
153145

146+
/**
147+
* BC - getArgs only returned 1 set of args in v1 instead of multiple sets of args in v2
148+
*
149+
* @param array $args
150+
* @return array
151+
*/
152+
private function preserveOldArgFormat(array $args)
153+
{
154+
if (isset($args[0]) && !is_array($args[0])) {
155+
$args = [$args];
156+
} elseif (empty($args)) {
157+
$args = [[]];
158+
}
159+
160+
return $args;
161+
}
162+
154163
/**
155164
* @param array $args
156165
* @param Input $input
@@ -206,32 +215,42 @@ private function doVerify(array $args, Input $input)
206215
public function run(Input $input, OutputInterface $output)
207216
{
208217
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.run.start', $this->exercise, $input));
209-
/** @var CliExecuteEvent $event */
210-
$event = $this->eventDispatcher->dispatch(
211-
new CliExecuteEvent('cli.run.student-execute.pre', new ArrayObject($this->exercise->getArgs()))
212-
);
218+
$success = true;
219+
foreach ($this->preserveOldArgFormat($this->exercise->getArgs()) as $i => $args) {
220+
/** @var CliExecuteEvent $event */
221+
$event = $this->eventDispatcher->dispatch(
222+
new CliExecuteEvent('cli.run.student-execute.pre', new ArrayObject($args))
223+
);
213224

214-
$args = $event->getArgs();
225+
$args = $event->getArgs();
215226

216-
if (count($args)) {
217-
$glue = max(array_map('strlen', $args->getArrayCopy())) > 30 ? "\n" : ', ';
227+
if (count($args)) {
228+
$glue = max(array_map('strlen', $args->getArrayCopy())) > 30 ? "\n" : ', ';
218229

219-
$output->writeTitle('Arguments');
220-
$output->write(implode($glue, $args->getArrayCopy()));
230+
$output->writeTitle('Arguments');
231+
$output->write(implode($glue, $args->getArrayCopy()));
232+
$output->emptyLine();
233+
}
234+
235+
$output->writeTitle("Output");
236+
$process = $this->getPhpProcess($input->getArgument('program'), $args);
237+
$process->start();
238+
$this->eventDispatcher->dispatch(
239+
new CliExecuteEvent('cli.run.student.executing', $args, ['output' => $output])
240+
);
241+
$process->wait(function ($outputType, $outputBuffer) use ($output) {
242+
$output->write($outputBuffer);
243+
});
221244
$output->emptyLine();
222-
}
223245

224-
$output->writeTitle("Output");
225-
$process = $this->getPhpProcess($input->getArgument('program'), $args);
226-
$process->start();
227-
$this->eventDispatcher->dispatch(
228-
new CliExecuteEvent('cli.run.student.executing', $args, ['output' => $output])
229-
);
230-
$process->wait(function ($outputType, $outputBuffer) use ($output) {
231-
$output->writeLine($outputBuffer);
232-
});
246+
if (!$process->isSuccessful()) {
247+
$success = false;
248+
}
249+
250+
$output->lineBreak();
251+
}
233252

234253
$this->eventDispatcher->dispatch(new ExerciseRunnerEvent('cli.run.finish', $this->exercise, $input));
235-
return $process->isSuccessful();
254+
return $success;
236255
}
237256
}

test/ExerciseRunner/CliRunnerTest.php

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ public function testVerifyThrowsExceptionIfSolutionFailsExecution()
7272
$this->exercise
7373
->expects($this->once())
7474
->method('getArgs')
75-
->will($this->returnValue([]));
75+
->will($this->returnValue([[]]));
7676

7777
$regex = "/^PHP Code failed to execute\\. Error: \"PHP Parse error: syntax error, unexpected end of file";
7878
$regex .= ", expecting ',' or ';'/";
@@ -134,7 +134,7 @@ public function testVerifyReturnsFailureIfUserSolutionFailsToExecute()
134134
$this->exercise
135135
->expects($this->once())
136136
->method('getArgs')
137-
->will($this->returnValue([1, 2, 3]));
137+
->will($this->returnValue([[1, 2, 3]]));
138138

139139
$failure = $this->runner->verify(new Input('app', ['program' => __DIR__ . '/../res/cli/user-error.php']));
140140

@@ -160,7 +160,7 @@ public function testVerifyReturnsFailureIfSolutionOutputDoesNotMatchUserOutput()
160160
$this->exercise
161161
->expects($this->once())
162162
->method('getArgs')
163-
->will($this->returnValue([1, 2, 3]));
163+
->will($this->returnValue([[1, 2, 3]]));
164164

165165
$failure = $this->runner->verify(new Input('app', ['program' => __DIR__ . '/../res/cli/user-wrong.php']));
166166

@@ -176,18 +176,25 @@ public function testVerifyReturnsFailureIfSolutionOutputDoesNotMatchUserOutput()
176176

177177
public function testRunPassesOutputAndReturnsSuccessIfScriptIsSuccessful()
178178
{
179-
$output = new StdOutput(new Color, $this->createMock(TerminalInterface::class));
179+
$color = new Color;
180+
$color->setForceStyle(true);
181+
$output = new StdOutput($color, $this->createMock(TerminalInterface::class));
180182

181183
$this->exercise
182184
->expects($this->once())
183185
->method('getArgs')
184-
->will($this->returnValue([1, 2, 3]));
186+
->will($this->returnValue([[1, 2, 3], [4, 5, 6]]));
185187

186188
$exp = "\n\e[1m\e[4mArguments\e[0m\e[0m\n";
187-
$exp .= "1, 2, 3\n\n";
188-
$exp .= "\e[1m\e[4m";
189-
$exp .= "Output\e[0m\e[0m\n";
189+
$exp .= "1, 2, 3\n";
190+
$exp .= "\n\e[1m\e[4mOutput\e[0m\e[0m\n";
190191
$exp .= "6\n";
192+
$exp .= "\e[33m\e[0m\n";
193+
$exp .= "\e[1m\e[4mArguments\e[0m\e[0m\n";
194+
$exp .= "4, 5, 6\n\n";
195+
$exp .= "\e[1m\e[4mOutput\e[0m\e[0m\n";
196+
$exp .= "15\n";
197+
$exp .= "\e[33m\e[0m";
191198

192199
$this->expectOutputString($exp);
193200

@@ -202,7 +209,7 @@ public function testRunPassesOutputAndReturnsFailureIfScriptFails()
202209
$this->exercise
203210
->expects($this->once())
204211
->method('getArgs')
205-
->will($this->returnValue([1, 2, 3]));
212+
->will($this->returnValue([[1, 2, 3]]));
206213

207214
$this->expectOutputRegex('/PHP Parse error: syntax error, unexpected end of file, expecting \',\' or \';\' /');
208215

0 commit comments

Comments
 (0)