Skip to content

Commit f56c445

Browse files
committed
Tests for results renderer
1 parent f55f6cf commit f56c445

8 files changed

+455
-0
lines changed

src/functions.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,17 @@ function mb_str_pad($input, $padLength, $padString = ' ', $padType = STR_PAD_RIG
1515
return str_pad($input, $padLength + $diff, $padString, $padType);
1616
}
1717
}
18+
19+
if (!function_exists('camel_case_to_kebab_case')) {
20+
21+
/**
22+
* @param string $string
23+
* @return string
24+
*/
25+
function camel_case_to_kebab_case($string)
26+
{
27+
return preg_replace_callback('/[A-Z]/', function ($matches) {
28+
return '-' . strtolower($matches[0]);
29+
}, $string);
30+
}
31+
}

test/ResultRenderer/ResultsRendererTest.php

Lines changed: 286 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,24 @@
44

55
use Colors\Color;
66
use PhpSchool\CliMenu\Terminal\TerminalInterface;
7+
use PhpSchool\PhpWorkshop\Exercise\ExerciseInterface;
8+
use PhpSchool\PhpWorkshop\Exercise\ProvidesSolution;
79
use PhpSchool\PhpWorkshop\ExerciseRepository;
810
use PhpSchool\PhpWorkshop\Factory\ResultRendererFactory;
11+
use PhpSchool\PhpWorkshop\Output\StdOutput;
912
use PhpSchool\PhpWorkshop\Result\Failure;
1013
use PhpSchool\PhpWorkshop\Result\ResultInterface;
14+
use PhpSchool\PhpWorkshop\Result\Success;
15+
use PhpSchool\PhpWorkshop\ResultAggregator;
1116
use PhpSchool\PhpWorkshop\ResultRenderer\FailureRenderer;
1217
use PhpSchool\PhpWorkshop\ResultRenderer\ResultRendererInterface;
1318
use PhpSchool\PhpWorkshop\ResultRenderer\ResultsRenderer;
19+
use PhpSchool\PhpWorkshop\Solution\SingleFileSolution;
20+
use PhpSchool\PhpWorkshop\UserState;
1421
use PhpSchool\PSX\Factory;
1522
use PhpSchool\PSX\SyntaxHighlighter;
1623
use PHPUnit_Framework_TestCase;
24+
use Prophecy\Argument;
1725

1826
/**
1927
* Class ResultsRendererTest
@@ -67,4 +75,282 @@ public function testLineBreak()
6775

6876
$this->assertSame("\e[33m──────────\e[0m", $renderer->lineBreak());
6977
}
78+
79+
public function testRenderSuccess()
80+
{
81+
$color = new Color;
82+
$color->setForceStyle(true);
83+
84+
$resultRendererFactory = new ResultRendererFactory;
85+
86+
$terminal = $this->prophesize(TerminalInterface::class);
87+
$terminal->getWidth()->willReturn(100);
88+
$terminal = $terminal->reveal();
89+
90+
$exerciseRepo = $this->prophesize(ExerciseRepository::class);
91+
$exerciseRepo->count()->willReturn(2);
92+
93+
$renderer = new ResultsRenderer(
94+
'app',
95+
$color,
96+
$terminal,
97+
$exerciseRepo->reveal(),
98+
(new Factory)->__invoke(),
99+
$resultRendererFactory
100+
);
101+
102+
$resultSet = new ResultAggregator;
103+
$resultSet->add(new Success('Success 1!'));
104+
$resultSet->add(new Success('Success 2!'));
105+
106+
$this->expectOutputString($this->getExpectedOutput());
107+
108+
$renderer->render(
109+
$resultSet,
110+
$this->createMock(ExerciseInterface::class),
111+
new UserState(['exercise1']),
112+
new StdOutput($color, $terminal)
113+
);
114+
}
115+
116+
public function testRenderSuccessWithSolution()
117+
{
118+
$color = new Color;
119+
$color->setForceStyle(true);
120+
121+
$resultRendererFactory = new ResultRendererFactory;
122+
123+
$terminal = $this->prophesize(TerminalInterface::class);
124+
$terminal->getWidth()->willReturn(100);
125+
$terminal = $terminal->reveal();
126+
127+
$exerciseRepo = $this->prophesize(ExerciseRepository::class);
128+
$exerciseRepo->count()->willReturn(2);
129+
130+
$tmpFile = sprintf('%s/%s/some-file', sys_get_temp_dir(), $this->getName());
131+
mkdir(dirname($tmpFile));
132+
file_put_contents($tmpFile, 'FILE CONTENTS');
133+
134+
$solution = new SingleFileSolution($tmpFile);
135+
136+
$exercise = $this->prophesize(ExerciseInterface::class);
137+
$exercise->willImplement(ProvidesSolution::class);
138+
$exercise->getSolution()->willReturn($solution);
139+
140+
$renderer = new ResultsRenderer(
141+
'app',
142+
$color,
143+
$terminal,
144+
$exerciseRepo->reveal(),
145+
(new Factory)->__invoke(),
146+
$resultRendererFactory
147+
);
148+
149+
$resultSet = new ResultAggregator;
150+
$resultSet->add(new Success('Success 1!'));
151+
$resultSet->add(new Success('Success 2!'));
152+
153+
$this->expectOutputString($this->getExpectedOutput());
154+
155+
$renderer->render(
156+
$resultSet,
157+
$exercise->reveal(),
158+
new UserState(['exercise1']),
159+
new StdOutput($color, $terminal)
160+
);
161+
162+
unlink($tmpFile);
163+
rmdir(dirname($tmpFile));
164+
}
165+
166+
public function testRenderSuccessWithPhpSolutionFileIsSyntaxHighlighted()
167+
{
168+
$color = new Color;
169+
$color->setForceStyle(true);
170+
171+
$resultRendererFactory = new ResultRendererFactory;
172+
173+
$terminal = $this->prophesize(TerminalInterface::class);
174+
$terminal->getWidth()->willReturn(100);
175+
$terminal = $terminal->reveal();
176+
177+
$exerciseRepo = $this->prophesize(ExerciseRepository::class);
178+
$exerciseRepo->count()->willReturn(2);
179+
180+
$tmpFile = sprintf('%s/%s/some-file.php', sys_get_temp_dir(), $this->getName());
181+
mkdir(dirname($tmpFile));
182+
file_put_contents($tmpFile, 'FILE CONTENTS');
183+
184+
$solution = new SingleFileSolution($tmpFile);
185+
186+
$exercise = $this->prophesize(ExerciseInterface::class);
187+
$exercise->willImplement(ProvidesSolution::class);
188+
$exercise->getSolution()->willReturn($solution);
189+
190+
$syntaxHighlighter = $this->prophesize(SyntaxHighlighter::class);
191+
$syntaxHighlighter->highlight('FILE CONTENTS')->willReturn('FILE CONTENTS');
192+
193+
$renderer = new ResultsRenderer(
194+
'app',
195+
$color,
196+
$terminal,
197+
$exerciseRepo->reveal(),
198+
$syntaxHighlighter->reveal(),
199+
$resultRendererFactory
200+
);
201+
202+
$resultSet = new ResultAggregator;
203+
$resultSet->add(new Success('Success 1!'));
204+
$resultSet->add(new Success('Success 2!'));
205+
206+
$this->expectOutputString($this->getExpectedOutput());
207+
208+
$renderer->render(
209+
$resultSet,
210+
$exercise->reveal(),
211+
new UserState(['exercise1']),
212+
new StdOutput($color, $terminal)
213+
);
214+
215+
unlink($tmpFile);
216+
rmdir(dirname($tmpFile));
217+
}
218+
219+
public function testRenderSuccessAndFailure()
220+
{
221+
$color = new Color;
222+
$color->setForceStyle(true);
223+
224+
$resultRendererFactory = new ResultRendererFactory;
225+
$resultRendererFactory->registerRenderer(Failure::class, FailureRenderer::class, function (Failure $failure) {
226+
$renderer = $this->prophesize(FailureRenderer::class);
227+
$renderer->render(Argument::type(ResultsRenderer::class))->willReturn($failure->getReason() . "\n");
228+
return $renderer->reveal();
229+
});
230+
231+
$terminal = $this->prophesize(TerminalInterface::class);
232+
$terminal->getWidth()->willReturn(100);
233+
$terminal = $terminal->reveal();
234+
235+
$exerciseRepo = $this->prophesize(ExerciseRepository::class);
236+
$exerciseRepo->count()->willReturn(2);
237+
238+
$renderer = new ResultsRenderer(
239+
'app',
240+
$color,
241+
$terminal,
242+
$exerciseRepo->reveal(),
243+
(new Factory)->__invoke(),
244+
$resultRendererFactory
245+
);
246+
247+
$resultSet = new ResultAggregator;
248+
$resultSet->add(new Success('Success 1!'));
249+
$resultSet->add(new Failure('Check 1', 'Failure'));
250+
$resultSet->add(new Failure('Check 2', 'Failure'));
251+
252+
$this->expectOutputString($this->getExpectedOutput());
253+
254+
$renderer->render(
255+
$resultSet,
256+
$this->createMock(ExerciseInterface::class),
257+
new UserState,
258+
new StdOutput($color, $terminal)
259+
);
260+
}
261+
262+
public function testAllSuccessResultsAreHoistedToTheTop()
263+
{
264+
$color = new Color;
265+
$color->setForceStyle(true);
266+
267+
$resultRendererFactory = new ResultRendererFactory;
268+
$resultRendererFactory->registerRenderer(Failure::class, FailureRenderer::class, function (Failure $failure) {
269+
$renderer = $this->prophesize(FailureRenderer::class);
270+
$renderer->render(Argument::type(ResultsRenderer::class))->willReturn($failure->getReason() . "\n");
271+
return $renderer->reveal();
272+
});
273+
274+
$terminal = $this->prophesize(TerminalInterface::class);
275+
$terminal->getWidth()->willReturn(100);
276+
$terminal = $terminal->reveal();
277+
278+
$exerciseRepo = $this->prophesize(ExerciseRepository::class);
279+
$exerciseRepo->count()->willReturn(2);
280+
281+
$renderer = new ResultsRenderer(
282+
'app',
283+
$color,
284+
$terminal,
285+
$exerciseRepo->reveal(),
286+
(new Factory)->__invoke(),
287+
$resultRendererFactory
288+
);
289+
290+
$resultSet = new ResultAggregator;
291+
$resultSet->add(new Failure('Failure 1', 'Failure 1'));
292+
$resultSet->add(new Success('Success 1!'));
293+
$resultSet->add(new Failure('Failure 2', 'Failure 2'));
294+
$resultSet->add(new Success('Success 2!'));
295+
296+
$this->expectOutputString($this->getExpectedOutput());
297+
298+
$renderer->render(
299+
$resultSet,
300+
$this->createMock(ExerciseInterface::class),
301+
new UserState,
302+
new StdOutput($color, $terminal)
303+
);
304+
}
305+
306+
public function testRenderAllFailures()
307+
{
308+
$color = new Color;
309+
$color->setForceStyle(true);
310+
311+
$resultRendererFactory = new ResultRendererFactory;
312+
$resultRendererFactory->registerRenderer(Failure::class, FailureRenderer::class, function (Failure $failure) {
313+
$renderer = $this->prophesize(FailureRenderer::class);
314+
$renderer->render(Argument::type(ResultsRenderer::class))->willReturn($failure->getReason() . "\n");
315+
return $renderer->reveal();
316+
});
317+
318+
$terminal = $this->prophesize(TerminalInterface::class);
319+
$terminal->getWidth()->willReturn(100);
320+
$terminal = $terminal->reveal();
321+
322+
$exerciseRepo = $this->prophesize(ExerciseRepository::class);
323+
$exerciseRepo->count()->willReturn(2);
324+
325+
$renderer = new ResultsRenderer(
326+
'app',
327+
$color,
328+
$terminal,
329+
$exerciseRepo->reveal(),
330+
(new Factory)->__invoke(),
331+
$resultRendererFactory
332+
);
333+
334+
$resultSet = new ResultAggregator;
335+
$resultSet->add(new Failure('Failure 1', 'Failure 1'));
336+
$resultSet->add(new Failure('Failure 2', 'Failure 2'));
337+
338+
$this->expectOutputString($this->getExpectedOutput());
339+
340+
$renderer->render(
341+
$resultSet,
342+
$this->createMock(ExerciseInterface::class),
343+
new UserState,
344+
new StdOutput($color, $terminal)
345+
);
346+
}
347+
348+
/**
349+
* @return string
350+
*/
351+
private function getExpectedOutput()
352+
{
353+
$name = camel_case_to_kebab_case($this->getName());
354+
return file_get_contents(sprintf('%s/../res/exercise-renderer/%s.txt', __DIR__, $name));
355+
}
70356
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
2+
*** RESULTS ***
3+
4+
 
5+
 ✔ Check: Success 1! 
6+
 
7+
8+
 
9+
 ✔ Check: Success 2! 
10+
 
11+
12+
 
13+
 ✗ Check: Failure 1 
14+
 
15+
16+
Failure 1
17+
 
18+
 ✗ Check: Failure 2 
19+
 
20+
21+
Failure 2
22+
────────────────────────────────────────────────────────────────────────────────────────────────────
23+
24+
 
25+
 Your solution was unsuccessful! 
26+
 
27+
28+
Your solution to didn't pass. Try again!
29+
30+
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
*** RESULTS ***
3+
4+
 
5+
 ✗ Check: Failure 1 
6+
 
7+
8+
Failure 1
9+
 
10+
 ✗ Check: Failure 2 
11+
 
12+
13+
Failure 2
14+
────────────────────────────────────────────────────────────────────────────────────────────────────
15+
16+
 
17+
 Your solution was unsuccessful! 
18+
 
19+
20+
Your solution to didn't pass. Try again!
21+
22+

0 commit comments

Comments
 (0)