Passed
Push — master ( 5545f1...83deac )
by Kirill
03:22
created

DeclarationsTest::testFileDeclarationDirectives()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 12
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 8
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 12
rs 10
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\Reactor;
13
14
use PHPUnit\Framework\TestCase;
15
use Psr\Container\ContainerInterface;
16
use Spiral\Reactor\AbstractDeclaration;
17
use Spiral\Reactor\ClassDeclaration;
18
use Spiral\Reactor\DeclarationInterface;
19
use Spiral\Reactor\FileDeclaration;
20
use Spiral\Reactor\NamedInterface;
21
use Spiral\Reactor\NamespaceDeclaration;
22
use Spiral\Reactor\Partial;
23
use Spiral\Reactor\Serializer;
24
use Spiral\Reactor\Traits\CommentTrait;
25
use Spiral\Reactor\Traits\NamedTrait;
26
use Spiral\Tests\Reactor\Fixture\DependedElement;
27
28
class DeclarationsTest extends TestCase
29
{
30
    //Simple test which touches a lot of methods
31
    public function testClassDeclaration(): ClassDeclaration
32
    {
33
        $declaration = new ClassDeclaration('MyClass');
34
        $declaration->setExtends('Record');
35
        $this->assertSame('Record', $declaration->getExtends());
36
37
        $declaration->addInterface('Traversable');
38
        $this->assertSame(['Traversable'], $declaration->getInterfaces());
39
40
        $this->assertTrue($declaration->hasInterface('Traversable'));
41
        $declaration->removeInterface('Traversable');
42
        $this->assertSame([], $declaration->getInterfaces());
43
44
        $declaration->constant('BOOT')
45
            ->setValue(true)
46
            ->setComment('Always boot');
47
48
        $this->assertTrue($declaration->getConstants()->has('BOOT'));
49
        $this->assertTrue($declaration->getConstants()->get('BOOT')->getValue());
50
51
        $declaration->property('names')
52
            ->setAccess(Partial\Property::ACCESS_PRIVATE)
53
            ->setComment(['This is names', '', '@var array'])
54
            ->setDefaultValue(['Anton', 'John']);
55
56
        $this->assertTrue($declaration->getProperties()->has('names'));
57
        $this->assertSame(
58
            ['Anton', 'John'],
59
            $declaration->getProperties()->get('names')->getDefaultValue()
60
        );
61
62
        $method = $declaration->method('sample');
63
        $method->parameter('input')->setType('int');
64
        $method->parameter('output')->setType('int')->setDefaultValue(null)->setPBR(true);
65
        $method->setAccess(Partial\Method::ACCESS_PUBLIC)->setStatic(true);
66
67
        $method->setSource([
68
            '$output = $input;',
69
            'return true;'
70
        ]);
71
72
        $this->assertSame(
73
            preg_replace('/\s+/', '', 'class MyClass extends Record
74
            {
75
                /**
76
                 * Always boot
77
                 */
78
                private const BOOT = true;
79
80
                /**
81
                 * This is names
82
                 *
83
                 * @var array
84
                 */
85
                private $names = [
86
                    \'Anton\',
87
                    \'John\'
88
                ];
89
90
                public static function sample(int $input, int &$output = null)
91
                {
92
                    $output = $input;
93
                    return true;
94
                }
95
            }'),
96
            preg_replace('/\s+/', '', $declaration->render())
97
        );
98
99
        return $declaration;
100
    }
101
102
    public function testFileDeclaration(): void
103
    {
104
        $declaration = new FileDeclaration('Spiral\\Custom_Namespace', 'This is test file');
105
        $declaration->addUse(ContainerInterface::class, 'Container');
106
107
        $this->assertSame('Spiral\\Custom_Namespace', $declaration->getNamespace());
108
109
        $declaration->addElement($this->testClassDeclaration());
110
111
        $this->assertSame(
112
            preg_replace('/\s+/', '', '
113
            <?php
114
            /**
115
             * This is test file
116
             */
117
             namespace Spiral\\Custom_Namespace;
118
119
             use Psr\Container\ContainerInterface as Container;
120
121
             class MyClass extends Record
122
             {
123
                 /**
124
                  * Always boot
125
                  */
126
                 private const BOOT = true;
127
128
                 /**
129
                  * This is names
130
                  *
131
                  * @var array
132
                  */
133
                 private $names = [
134
                     \'Anton\',
135
                     \'John\'
136
                 ];
137
138
                 public static function sample(int $input, int &$output = null)
139
                 {
140
                     $output = $input;
141
                     return true;
142
                 }
143
             }'),
144
            preg_replace('/\s+/', '', (string)$declaration)
145
        );
146
    }
147
148
    public function testDependedFileImport(): void
149
    {
150
        $declaration = new FileDeclaration('Spiral\\Custom_Namespace', 'This is test file');
151
        $declaration->addElement(new DependedElement('depended'));
152
153
        $this->assertStringContainsString(
154
            preg_replace('/\s+/', '', 'use Spiral\Reactor\DependedInterface as DependencyAlias;'),
155
            preg_replace('/\s+/', '', (string)$declaration)
156
        );
157
    }
158
159
    public function testDependedNamespaceImport(): void
160
    {
161
        $declaration = new NamespaceDeclaration('Custom_Namespace');
162
        $declaration->addElement(new DependedElement('depended'));
163
164
        $this->assertStringContainsString(
165
            preg_replace('/\s+/', '', 'use Spiral\Reactor\DependedInterface as DependencyAlias;'),
166
            preg_replace('/\s+/', '', $declaration->render())
167
        );
168
    }
169
170
    public function testNamespaceDeclaration(): void
171
    {
172
        $declaration = new NamespaceDeclaration('Spiral\\Custom_Namespace', 'This is test namespace');
173
        $declaration->addUse(ContainerInterface::class, 'Container');
174
175
        $declaration->addElement($this->testClassDeclaration());
176
177
        $this->assertSame(
178
            preg_replace('/\s+/', '', '
179
            /**
180
             * This is test namespace
181
             */
182
             namespace Spiral\\Custom_Namespace {
183
                 use Psr\Container\ContainerInterface as Container;
184
185
                 class MyClass extends Record
186
                 {
187
                     /**
188
                      * Always boot
189
                      */
190
                     private const BOOT = true;
191
192
                     /**
193
                      * This is names
194
                      *
195
                      * @var array
196
                      */
197
                     private $names = [
198
                         \'Anton\',
199
                         \'John\'
200
                     ];
201
202
                     public static function sample(int $input, int &$output = null)
203
                     {
204
                         $output = $input;
205
                         return true;
206
                     }
207
                 }
208
             }'),
209
            preg_replace('/\s+/', '', $declaration->render())
210
        );
211
    }
212
213
    public function testFileDeclaration2(): void
214
    {
215
        $f = new FileDeclaration();
216
        $f->setNamespace('Spiral\\Test');
217
        $this->assertStringContainsString('namespace Spiral\\Test;', $f->render());
218
219
        $c = new ClassDeclaration('TestClass');
220
        $c->addTrait(NamedTrait::class);
221
222
        $f->addElement($c);
223
        $this->assertTrue($f->getElements()->has('TestClass'));
224
        $this->assertStringContainsString('use Spiral\\Reactor\\Traits\\NamedTrait;', $f->render());
225
    }
226
227
    public function testFileDeclarationDirectives(): void
228
    {
229
        $f = new FileDeclaration();
230
        $this->assertStringNotContainsString('declare', $f->render());
231
232
        $f->setDirectives();
233
        $this->assertStringNotContainsString('declare', $f->render());
234
235
        $f->setDirectives('strict_types=1', 'ticks=1');
236
        $this->assertStringContainsString('declare', $f->render());
237
        $this->assertStringContainsString('strict_types=1', $f->render());
238
        $this->assertStringContainsString('ticks=1', $f->render());
239
    }
240
241
    public function testNamespaceDeclaration2(): void
242
    {
243
        $f = new NamespaceDeclaration('Spiral\\Test');
244
245
        $c = new ClassDeclaration('TestClass', AbstractDeclaration::class, [
246
            DeclarationInterface::class
247
        ]);
248
249
        $c->addTrait(NamedTrait::class);
250
        $this->assertCount(1, $c->getTraits());
251
252
        $c->setTraits([CommentTrait::class]);
253
        $this->assertCount(1, $c->getTraits());
254
255
        $this->assertCount(0, $c->getMethods());
256
        $f->addElement($c);
257
258
        $this->assertTrue($f->getElements()->has('TestClass'));
259
        $this->assertStringContainsString('use Spiral\\Reactor\\Traits\\CommentTrait;', $f->render());
260
261
        $c->removeTrait(CommentTrait::class);
262
        $this->assertStringNotContainsString('use Spiral\\Reactor\\Traits\\CommentTrait;', $f->render());
263
264
        $c->setComment('hello world');
265
        $this->assertStringContainsString('hello world', $f->render());
266
    }
267
268
    public function testUses(): void
269
    {
270
        $f = new NamespaceDeclaration('Spiral\\Test');
271
        $f->addUse(AbstractDeclaration::class);
272
        $f->addUse(NamedInterface::class, 'Named');
273
274
        $this->assertTrue($f->uses(AbstractDeclaration::class));
275
        $this->assertTrue($f->uses(NamedInterface::class));
276
277
        $this->assertStringContainsString("use Spiral\Reactor\AbstractDeclaration;", $f->render());
278
        $this->assertStringContainsString("use Spiral\Reactor\NamedInterface as Named;", $f->render());
279
280
        $f->removeUse(NamedInterface::class);
281
        $this->assertStringContainsString("use Spiral\Reactor\AbstractDeclaration;", $f->render());
282
        $this->assertStringNotContainsString("use Spiral\Reactor\NamedInterface as Named;", $f->render());
283
284
        $f->addUses([
285
            NamedInterface::class => 'Named',
286
            Serializer::class     => null
287
        ]);
288
289
        $this->assertStringContainsString("use Spiral\Reactor\AbstractDeclaration;", $f->render());
290
        $this->assertStringContainsString("use Spiral\Reactor\Serializer;", $f->render());
291
        $this->assertStringContainsString("use Spiral\Reactor\NamedInterface as Named;", $f->render());
292
293
        $f->setUses([
294
            NamedInterface::class => 'Named',
295
            Serializer::class     => null
296
        ]);
297
298
        $this->assertStringNotContainsString("use Spiral\Reactor\AbstractDeclaration;", $f->render());
299
        $this->assertStringContainsString("use Spiral\Reactor\Serializer;", $f->render());
300
        $this->assertStringContainsString("use Spiral\Reactor\NamedInterface as Named;", $f->render());
301
    }
302
303
    public function testComment(): void
304
    {
305
        $c = new ClassDeclaration('TestClass', AbstractDeclaration::class, [
306
            DeclarationInterface::class
307
        ]);
308
309
        $c->setComment('');
310
        $this->assertStringNotContainsString('/**', $c->render());
311
312
        $c->setComment("/**\nhello world\n*/");
313
        $this->assertStringContainsString('hello world', $c->render());
314
    }
315
316
    public function testCommentLines(): void
317
    {
318
        $comment = new Partial\Comment();
319
        $comment->setString("/**\n * hello world\n/*\n *add space\n*/\n *    indent 3 spaces\n */");
320
        $this->assertStringContainsString(
321
            "/**\n * hello world\n * add space\n *    indent 3 spaces\n */",
322
            $comment->render()
323
        );
324
    }
325
}
326