Passed
Pull Request — master (#653)
by Aleksei
07:43
created

ImportedStackTest::testGrid()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 43
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 34
nc 1
nop 0
dl 0
loc 43
rs 9.376
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Spiral Framework.
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Spiral\Tests\Stempler\Transform;
13
14
use Spiral\Stempler\Builder;
15
use Spiral\Stempler\Directive\LoopDirective;
16
use Spiral\Stempler\Loader\LoaderInterface;
17
use Spiral\Stempler\Loader\StringLoader;
18
use Spiral\Stempler\Node\Aggregate;
19
use Spiral\Stempler\Transform\Finalizer\DynamicToPHP;
20
use Spiral\Stempler\Transform\Finalizer\StackCollector;
21
use Spiral\Stempler\Transform\Finalizer\TrimRaw;
22
use Spiral\Stempler\Transform\Merge\ExtendsParent;
23
use Spiral\Stempler\Transform\Merge\ResolveImports;
24
use Spiral\Stempler\Transform\Visitor\DefineAttributes;
25
use Spiral\Stempler\Transform\Visitor\DefineBlocks;
26
use Spiral\Stempler\Transform\Visitor\DefineHidden;
27
use Spiral\Stempler\Transform\Visitor\DefineStacks;
28
29
class ImportedStackTest extends BaseTest
30
{
31
    public function testEmptyStack(): void
32
    {
33
        $doc = $this->parse('<stack:collect name="css"/>');
34
35
        $this->assertInstanceOf(Aggregate::class, $doc->nodes[0]);
36
        $this->assertSame([], $doc->nodes[0]->nodes);
37
    }
38
39
    public function testImportedStack(): void
40
    {
41
        $loader = $loader ?? new StringLoader();
42
        $loader->set(
43
            'root',
44
            '<use:element path="import" as="url"/>
45
<stack:collect name="css"/>
46
<url href="google.com">hello world</url>
47
'
48
        );
49
        $loader->set('import', '
50
<stack:push name="css">css</stack:push>
51
<a href="${href}"><block:context/></a>
52
');
53
54
        $builder = $this->getBuilder($loader, []);
55
56
        $this->assertSame(
57
            'css<a href="google.com">hello world</a>',
58
            $builder->compile('root')->getContent()
59
        );
60
    }
61
62
    public function testStackDefinedInParent(): void
63
    {
64
        $loader = $loader ?? new StringLoader();
65
        $loader->set(
66
            'root',
67
            '<extends:parent/>
68
<use:element path="import" as="url"/>
69
<block:body>
70
    <url href="google.com">hello world</url>
71
</block:body>
72
'
73
        );
74
75
        $loader->set(
76
            'parent',
77
            '<html>
78
            <stack:collect name="css"/>
79
            <body>${body}</body>
80
            <stack:collect name="js"/>
81
            </html>'
82
        );
83
84
        $loader->set('import', '
85
<stack:push name="css">css</stack:push>
86
<a href="${href}"><block:context/></a>
87
');
88
89
        $builder = $this->getBuilder($loader, []);
90
91
        $this->assertSame(
92
            '<html>css<body><a href="google.com">hello world</a></body></html>',
93
            $builder->compile('root')->getContent()
94
        );
95
    }
96
97
    public function testStackDefinedInParentWithChild(): void
98
    {
99
        $loader = $loader ?? new StringLoader();
100
        $loader->set(
101
            'root',
102
            '<extends:parent/>
103
<use:element path="import" as="url"/>
104
105
<block:body>
106
    <stack:push name="js">js</stack:push>
107
    <url href="google.com">hello world</url>
108
</block:body>
109
'
110
        );
111
112
        $loader->set(
113
            'parent',
114
            '<html>
115
            <stack:collect name="css"/>
116
            <body>${body}</body>
117
            <stack:collect name="js"/>
118
            </html>'
119
        );
120
121
        $loader->set('import', '
122
<stack:push name="css">css</stack:push>
123
<a href="${href}"><block:context/></a>
124
');
125
126
        $builder = $this->getBuilder($loader, []);
127
128
        $this->assertSame(
129
            '<html>css<body><a href="google.com">hello world</a></body>js</html>',
130
            $builder->compile('root')->getContent()
131
        );
132
    }
133
134
    public function testGrid(): void
135
    {
136
        $loader = $loader ?? new StringLoader();
137
        $loader->set(
138
            'root',
139
            '<use:dir dir="grid" ns="grid"/>
140
<grid:render>
141
    some arbitrary text
142
143
    <grid:cell title="ID">value</grid:cell>
144
    <grid:cell title="Title">value</grid:cell>
145
</grid:render>
146
'
147
        );
148
149
        $loader->set(
150
            'grid' . DIRECTORY_SEPARATOR . 'render',
151
            '
152
<table>
153
<thead>
154
<stack:collect name="head" level="1"/>
155
</thead>
156
<tbody>
157
<stack:collect name="body" level="1"/>
158
</tbody>
159
<hidden>${context}</hidden>
160
</table>
161
'
162
        );
163
164
        $loader->set(
165
            'grid' . DIRECTORY_SEPARATOR . 'cell',
166
            '
167
<stack:push name="head"><tr>${title}</tr></stack:push>
168
<stack:push name="body"><td>${context}</td></stack:push>
169
'
170
        );
171
172
        $builder = $this->getBuilder($loader, []);
173
174
        $this->assertSame(
175
            '<table><thead><tr>ID</tr><tr>Title</tr></thead><tbody><td>value</td><td>value</td></tbody></table>',
176
            $builder->compile('root')->getContent()
177
        );
178
    }
179
180
    protected function getBuilder(LoaderInterface $loader, array $visitors): Builder
181
    {
182
        $builder = parent::getBuilder($loader, $visitors);
183
184
        // import resolution
185
        $builder->addVisitor(new ResolveImports($builder), Builder::STAGE_TRANSFORM);
186
        $builder->addVisitor(new ExtendsParent($builder), Builder::STAGE_TRANSFORM);
187
188
        // so we can inject into PHP
189
        $dynamic = new DynamicToPHP();
190
        $dynamic->addDirective(new LoopDirective());
191
192
        $builder->addVisitor($dynamic);
193
        $builder->addVisitor(new StackCollector(), Builder::STAGE_FINALIZE);
194
        $builder->addVisitor(new TrimRaw(), Builder::STAGE_FINALIZE);
195
196
        return $builder;
197
    }
198
199
    protected function getVisitors(): array
200
    {
201
        return [
202
            new DefineAttributes(),
203
            new DefineBlocks(),
204
            new DefineStacks(),
205
            new DefineHidden()
206
        ];
207
    }
208
}
209