Passed
Pull Request — master (#8)
by Victor
03:41
created

testExtendedTemplatesShouldApplyCorrectModels()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
namespace Shoot\Shoot\Tests;
5
6
use PHPUnit\Framework\MockObject\MockObject;
7
use PHPUnit\Framework\TestCase;
8
use Psr\Http\Message\ServerRequestInterface;
9
use Shoot\Shoot\Extension;
10
use Shoot\Shoot\Middleware\PresenterMiddleware;
11
use Shoot\Shoot\Pipeline;
12
use Shoot\Shoot\Tests\Mocks\ContainerStub;
13
use Shoot\Shoot\Twig\PatchingCompiler;
14
use Twig_Environment as Environment;
15
use Twig_Error_Runtime;
16
use Twig_Loader_Filesystem as FilesystemLoader;
17
18
final class TwigIntegrationTest extends TestCase
19
{
20
    /** @var Pipeline */
21
    private $pipeline;
22
23
    /** @var ServerRequestInterface|MockObject */
24
    private $request;
25
26
    /** @var Environment */
27
    private $twig;
28
29
    /**
30
     * @return void
31
     */
32
    protected function setUp()
33
    {
34
        $container = new ContainerStub();
35
        $pipeline = new Pipeline([new PresenterMiddleware($container)]);
36
        $extension = new Extension($pipeline);
37
38
        $loader = new FilesystemLoader([realpath(__DIR__ . '/Fixtures/Templates')]);
39
        $twig = new Environment($loader, ['cache' => false, 'strict_variables' => true]);
40
        $twig->addExtension($extension);
41
        $twig->setCompiler(new PatchingCompiler($twig));
42
43
        $this->pipeline = $pipeline;
44
        $this->request = $this->createMock(ServerRequestInterface::class);
45
        $this->twig = $twig;
46
    }
47
48
    /**
49
     * @return void
50
     */
51
    public function testShouldRenderASingleModel()
52
    {
53
        $output = $this->renderTemplate('item.twig');
54
55
        $this->assertSame([
56
            '## item',
57
            'description',
58
        ], $output);
59
    }
60
61
    /**
62
     * @return void
63
     */
64
    public function testShouldRenderAListOfModels()
65
    {
66
        $output = $this->renderTemplate('item_list.twig');
67
68
        $this->assertSame([
69
            '# items',
70
            '## item 1',
71
            'description',
72
            '## item 2',
73
            'description',
74
            '## item 3',
75
            'description',
76
        ], $output);
77
    }
78
79
    /**
80
     * @return void
81
     */
82
    public function testAssigningMultipleModelsToAViewShouldThrowAnException()
83
    {
84
        $this->expectExceptionMessage('model has already been assigned');
85
86
        $this->renderTemplate('multiple_models.twig');
87
    }
88
89
    /**
90
     * @return void
91
     */
92
    public function testEmbeddedTemplatesShouldReceiveAllVariables()
93
    {
94
        $output = $this->renderTemplate('has_embedded_template.twig');
95
96
        $this->assertSame([
97
            '# title: item',
98
            '## subtitle: subtitle',
99
            'description',
100
        ], $output);
101
    }
102
103
    /**
104
     * @return void
105
     */
106
    public function testOptionalBlocksShouldBeHiddenIfTheyFail()
107
    {
108
        $output = $this->renderTemplate('optional_runtime_exception.twig');
109
110
        $this->assertContains('header', $output);
111
        $this->assertNotContains('should not be rendered', $output);
112
        $this->assertContains('footer', $output);
113
    }
114
115
    /**
116
     * @return void
117
     */
118
    public function testOptionalBlocksShouldNotSuppressUnknownVariables()
119
    {
120
        $this->expectException(Twig_Error_Runtime::class);
121
122
        $this->renderTemplate('optional_unknown_variable.twig');
123
    }
124
125
    /**
126
     * @return void
127
     */
128
    public function testNestedOptionalBlocksShouldNotAffectedParents()
129
    {
130
        $output = $this->renderTemplate('optional_nested.twig');
131
132
        $this->assertContains('header', $output);
133
        $this->assertNotContains('should not be rendered', $output);
134
        $this->assertContains('not affected', $output);
135
        $this->assertContains('footer', $output);
136
    }
137
138
    /**
139
     * @return void
140
     */
141
    public function testExtendedTemplatesShouldApplyCorrectModels()
142
    {
143
        $output = $this->renderTemplate('page.twig');
144
145
        $this->assertContains('<title>title</title>', $output);
146
        $this->assertContains('<h1>body</h1>', $output);
147
    }
148
149
    /**
150
     * @param string $template
151
     *
152
     * @return string[]
153
     */
154
    private function renderTemplate(string $template): array
155
    {
156
        return $this->pipeline->withRequest($this->request, function () use ($template): array {
157
            $output = $this->twig->render($template);
158
            $output = trim($output);
159
            $output = explode(PHP_EOL, $output);
160
            $output = array_map('trim', $output);
161
162
            return $output;
163
        });
164
    }
165
}
166