Passed
Push — master ( a53d55...43aca1 )
by Maximilian
03:50
created

APLDocumentTest   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 445
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 265
dl 0
loc 445
rs 10
c 1
b 0
f 1
wmc 17

17 Methods

Rating   Name   Duplication   Size   Complexity  
A testAPLDocumentWithSettings() 0 26 1
A testAPLDocumentComplexIntegration() 0 41 1
A testAPLDocumentWithAllBasicProperties() 0 26 1
A testAPLDocumentWithComplexMainTemplate() 0 20 1
A testAPLDocumentWithExport() 0 21 1
A testAPLDocumentWithResources() 0 26 1
A testAPLDocumentWithImports() 0 20 1
A testAPLDocumentWithLayouts() 0 30 1
A testAPLDocumentWithGraphics() 0 21 1
A testAPLDocumentWithEnvironment() 0 19 1
A testAPLDocumentJsonSerialize() 0 25 1
A testAPLDocumentWithCommands() 0 22 1
A testAPLDocumentWithExtensions() 0 19 1
A testAPLDocumentWithBindings() 0 23 1
A testAPLDocumentBasic() 0 17 1
A testAPLDocumentWithStyles() 0 28 1
A testAPLDocumentWithEventHandlers() 0 27 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MaxBeckers\AmazonAlexa\Test\Response\Directives\APL\Document;
6
7
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Component\TextComponent;
8
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\APLDocument;
9
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\BackgroundType;
10
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Bind;
11
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\BindType;
12
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Command;
13
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Environment;
14
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Export;
15
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\ExportItem;
16
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Extension;
17
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Gradient;
18
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Graphic;
19
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Import;
20
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\ImportType;
21
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\KeyHandler;
22
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Layout;
23
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\LayoutDirection;
24
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\LayoutParameter;
25
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\LayoutParameterType;
26
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\MainTemplate;
27
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Parameter;
28
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\ParameterType;
29
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\PseudoLocalization;
30
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Resource;
31
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Settings;
32
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Style;
33
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\StyleValue;
34
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\TickHandler;
35
use MaxBeckers\AmazonAlexa\Response\Directives\APL\StandardCommand\LogCommand;
36
use MaxBeckers\AmazonAlexa\Response\Directives\APL\StandardCommand\SetValueCommand;
37
use PHPUnit\Framework\TestCase;
38
39
class APLDocumentTest extends TestCase
40
{
41
    public function testAPLDocumentBasic(): void
42
    {
43
        $mainTemplate = new MainTemplate(
44
            parameters: ['payload'],
45
            items: []
46
        );
47
48
        $document = new APLDocument(
49
            mainTemplate: $mainTemplate
50
        );
51
52
        $this->assertInstanceOf(MainTemplate::class, $document->mainTemplate);
53
        $this->assertEquals('APL', $document->type);
54
        $this->assertEquals('2024.3', $document->version);
55
        $this->assertNull($document->background);
56
        $this->assertNull($document->description);
57
        $this->assertNull($document->theme);
58
    }
59
60
    public function testAPLDocumentWithAllBasicProperties(): void
61
    {
62
        $mainTemplate = new MainTemplate(
63
            parameters: ['payload', 'datasource']
64
        );
65
66
        $background = new Gradient(
67
            colorRange: ['red', 'blue'],
68
            type: BackgroundType::LINEAR,
69
            angle: 45
70
        );
71
72
        $document = new APLDocument(
73
            mainTemplate: $mainTemplate,
74
            type: 'APL',
75
            version: '2024.1',
76
            background: $background,
77
            description: 'Test APL Document',
78
            theme: 'dark'
79
        );
80
81
        $this->assertEquals('APL', $document->type);
82
        $this->assertEquals('2024.1', $document->version);
83
        $this->assertInstanceOf(Gradient::class, $document->background);
84
        $this->assertEquals('Test APL Document', $document->description);
85
        $this->assertEquals('dark', $document->theme);
86
    }
87
88
    public function testAPLDocumentWithCommands(): void
89
    {
90
        $mainTemplate = new MainTemplate();
91
92
        $parameter = new Parameter(
93
            name: 'message',
94
            type: ParameterType::STRING,
95
            default: 'Hello World'
96
        );
97
98
        $command = new Command(
99
            parameters: [$parameter],
100
            commands: [new LogCommand(message: 'Test log')]
101
        );
102
103
        $document = new APLDocument(
104
            mainTemplate: $mainTemplate,
105
            commands: ['testCommand' => $command]
106
        );
107
108
        $this->assertArrayHasKey('testCommand', $document->commands);
109
        $this->assertInstanceOf(Command::class, $document->commands['testCommand']);
110
    }
111
112
    public function testAPLDocumentWithEnvironment(): void
113
    {
114
        $mainTemplate = new MainTemplate();
115
116
        $environment = new Environment(
117
            lang: 'en-US',
118
            layoutDirection: LayoutDirection::LTR,
119
            parameters: ['param1', 'param2']
120
        );
121
122
        $document = new APLDocument(
123
            mainTemplate: $mainTemplate,
124
            environment: $environment
125
        );
126
127
        $this->assertInstanceOf(Environment::class, $document->environment);
128
        $this->assertEquals('en-US', $document->environment->lang);
129
        $this->assertEquals(LayoutDirection::LTR, $document->environment->layoutDirection);
130
        $this->assertEquals(['param1', 'param2'], $document->environment->parameters);
131
    }
132
133
    public function testAPLDocumentWithExport(): void
134
    {
135
        $mainTemplate = new MainTemplate();
136
137
        $exportItem = new ExportItem(
138
            name: 'TestLayout',
139
            description: 'A test layout for export'
140
        );
141
142
        $export = new Export(
143
            layouts: [$exportItem]
144
        );
145
146
        $document = new APLDocument(
147
            mainTemplate: $mainTemplate,
148
            export: $export
149
        );
150
151
        $this->assertInstanceOf(Export::class, $document->export);
152
        $this->assertCount(1, $document->export->layouts);
153
        $this->assertEquals('TestLayout', $document->export->layouts[0]->name);
154
    }
155
156
    public function testAPLDocumentWithExtensions(): void
157
    {
158
        $mainTemplate = new MainTemplate();
159
160
        $extension = new Extension(
161
            name: 'aplext:backstack',
162
            uri: 'aplext:backstack:10',
163
            required: true
164
        );
165
166
        $document = new APLDocument(
167
            mainTemplate: $mainTemplate,
168
            extensions: [$extension]
169
        );
170
171
        $this->assertCount(1, $document->extensions);
172
        $this->assertInstanceOf(Extension::class, $document->extensions[0]);
173
        $this->assertEquals('aplext:backstack', $document->extensions[0]->name);
174
        $this->assertTrue($document->extensions[0]->required);
175
    }
176
177
    public function testAPLDocumentWithGraphics(): void
178
    {
179
        $mainTemplate = new MainTemplate();
180
181
        $graphic = new Graphic(
182
            height: 100,
183
            width: 100,
184
            type: 'AVG',
185
            version: '1.2'
186
        );
187
        $graphic->description = 'testGraphic';
188
189
        $document = new APLDocument(
190
            mainTemplate: $mainTemplate,
191
            graphics: [$graphic]
192
        );
193
194
        $this->assertCount(1, $document->graphics);
195
        $this->assertInstanceOf(Graphic::class, $document->graphics[0]);
196
        $this->assertEquals('testGraphic', $document->graphics[0]->description);
197
        $this->assertEquals(100, $document->graphics[0]->height);
198
    }
199
200
    public function testAPLDocumentWithEventHandlers(): void
201
    {
202
        $mainTemplate = new MainTemplate();
203
204
        $keyHandler = new KeyHandler(
205
            commands: [new LogCommand(message: 'Key pressed')],
206
            propagate: false
207
        );
208
209
        $tickHandler = new TickHandler(
210
            commands: [new SetValueCommand(componentId: 'timer', property: 'text', value: '${time}')],
211
            minimumDelay: 1000
212
        );
213
214
        $document = new APLDocument(
215
            mainTemplate: $mainTemplate,
216
            handleKeyDown: [$keyHandler],
217
            handleTick: [$tickHandler]
218
        );
219
220
        $this->assertCount(1, $document->handleKeyDown);
221
        $this->assertInstanceOf(KeyHandler::class, $document->handleKeyDown[0]);
222
        $this->assertFalse($document->handleKeyDown[0]->propagate);
223
224
        $this->assertCount(1, $document->handleTick);
225
        $this->assertInstanceOf(TickHandler::class, $document->handleTick[0]);
226
        $this->assertEquals(1000, $document->handleTick[0]->minimumDelay);
227
    }
228
229
    public function testAPLDocumentWithImports(): void
230
    {
231
        $mainTemplate = new MainTemplate();
232
233
        $import = new Import(
234
            name: 'alexa-layouts',
235
            version: '1.7.0',
236
            type: ImportType::ALL_OF,
237
            source: 'https://example.com/layouts.json'
238
        );
239
240
        $document = new APLDocument(
241
            mainTemplate: $mainTemplate,
242
            import: [$import]
243
        );
244
245
        $this->assertCount(1, $document->import);
246
        $this->assertInstanceOf(Import::class, $document->import[0]);
247
        $this->assertEquals('alexa-layouts', $document->import[0]->name);
248
        $this->assertEquals(ImportType::ALL_OF, $document->import[0]->type);
249
    }
250
251
    public function testAPLDocumentWithLayouts(): void
252
    {
253
        $mainTemplate = new MainTemplate();
254
255
        $layoutParameter = new LayoutParameter(
256
            name: 'title',
257
            type: LayoutParameterType::STRING,
258
            default: 'Default Title'
259
        );
260
261
        $textComponent = new TextComponent(
262
            text: '${title}',
263
            fontSize: '20dp'
264
        );
265
266
        $layout = new Layout(
267
            parameters: [$layoutParameter],
268
            items: [$textComponent],
269
            description: 'A simple text layout'
270
        );
271
272
        $document = new APLDocument(
273
            mainTemplate: $mainTemplate,
274
            layouts: ['SimpleText' => $layout]
275
        );
276
277
        $this->assertArrayHasKey('SimpleText', $document->layouts);
278
        $this->assertInstanceOf(Layout::class, $document->layouts['SimpleText']);
279
        $this->assertEquals('A simple text layout', $document->layouts['SimpleText']->description);
280
        $this->assertCount(1, $document->layouts['SimpleText']->parameters);
281
    }
282
283
    public function testAPLDocumentWithResources(): void
284
    {
285
        $mainTemplate = new MainTemplate();
286
287
        $resource = new Resource(
288
            colors: [
289
                'primaryColor' => '#FF0000',
290
                'secondaryColor' => '#00FF00',
291
            ],
292
            dimensions: [
293
                'headerHeight' => '80dp',
294
                'padding' => '16dp',
295
            ],
296
            description: 'Primary color resources'
297
        );
298
299
        $document = new APLDocument(
300
            mainTemplate: $mainTemplate,
301
            resources: [$resource]
302
        );
303
304
        $this->assertCount(1, $document->resources);
305
        $this->assertInstanceOf(Resource::class, $document->resources[0]);
306
        $this->assertEquals('Primary color resources', $document->resources[0]->description);
307
        $this->assertArrayHasKey('primaryColor', $document->resources[0]->colors);
308
        $this->assertEquals('#FF0000', $document->resources[0]->colors['primaryColor']);
309
    }
310
311
    public function testAPLDocumentWithSettings(): void
312
    {
313
        $mainTemplate = new MainTemplate();
314
315
        $pseudoLocalization = new PseudoLocalization(
316
            enabled: true,
317
            expansionPercentage: 50
318
        );
319
320
        $settings = new Settings(
321
            idleTimeout: 30000,
322
            pseudoLocalization: $pseudoLocalization,
323
            supportsResizing: true
324
        );
325
326
        $document = new APLDocument(
327
            mainTemplate: $mainTemplate,
328
            settings: $settings
329
        );
330
331
        $this->assertInstanceOf(Settings::class, $document->settings);
332
        $this->assertEquals(30000, $document->settings->idleTimeout);
333
        $this->assertTrue($document->settings->supportsResizing);
334
        $this->assertInstanceOf(PseudoLocalization::class, $document->settings->pseudoLocalization);
335
        $this->assertTrue($document->settings->pseudoLocalization->enabled);
336
        $this->assertEquals(50, $document->settings->pseudoLocalization->expansionPercentage);
337
    }
338
339
    public function testAPLDocumentWithStyles(): void
340
    {
341
        $mainTemplate = new MainTemplate();
342
343
        $styleValue = new StyleValue(
344
            when: '${viewport.theme == "dark"}',
345
            properties: [
346
                'color' => 'white',
347
                'backgroundColor' => 'black',
348
            ]
349
        );
350
351
        $style = new Style(
352
            description: 'Base text style',
353
            extends: 'baseStyle',
354
            values: [$styleValue]
355
        );
356
357
        $document = new APLDocument(
358
            mainTemplate: $mainTemplate,
359
            styles: [$style]
360
        );
361
362
        $this->assertCount(1, $document->styles);
363
        $this->assertInstanceOf(Style::class, $document->styles[0]);
364
        $this->assertEquals('Base text style', $document->styles[0]->description);
365
        $this->assertEquals('baseStyle', $document->styles[0]->extends);
366
        $this->assertCount(1, $document->styles[0]->values);
367
    }
368
369
    public function testAPLDocumentWithComplexMainTemplate(): void
370
    {
371
        $textComponent = new TextComponent(
372
            text: '${payload.title}',
373
            fontSize: '24dp',
374
            color: 'white'
375
        );
376
377
        $mainTemplate = new MainTemplate(
378
            parameters: ['payload', 'datasource'],
379
            items: [$textComponent]
380
        );
381
382
        $document = new APLDocument(
383
            mainTemplate: $mainTemplate
384
        );
385
386
        $this->assertCount(2, $document->mainTemplate->parameters);
387
        $this->assertCount(1, $document->mainTemplate->items);
388
        $this->assertInstanceOf(TextComponent::class, $document->mainTemplate->items[0]);
389
    }
390
391
    public function testAPLDocumentJsonSerialize(): void
392
    {
393
        $mainTemplate = new MainTemplate(
394
            parameters: ['payload']
395
        );
396
397
        $document = new APLDocument(
398
            mainTemplate: $mainTemplate,
399
            type: 'APL',
400
            version: '2024.3',
401
            description: 'Test document',
402
            theme: 'light'
403
        );
404
405
        $json = $document->jsonSerialize();
406
407
        $this->assertArrayHasKey('type', $json);
408
        $this->assertEquals('APL', $json['type']);
409
        $this->assertArrayHasKey('version', $json);
410
        $this->assertEquals('2024.3', $json['version']);
411
        $this->assertArrayHasKey('mainTemplate', $json);
412
        $this->assertArrayHasKey('description', $json);
413
        $this->assertEquals('Test document', $json['description']);
414
        $this->assertArrayHasKey('theme', $json);
415
        $this->assertEquals('light', $json['theme']);
416
    }
417
418
    public function testAPLDocumentWithBindings(): void
419
    {
420
        $bind = new Bind(
421
            name: 'currentTime',
422
            value: '${utcTime}',
423
            type: BindType::STRING
424
        );
425
426
        $layout = new Layout(
427
            bind: [$bind],
428
            items: []
429
        );
430
431
        $mainTemplate = new MainTemplate();
432
433
        $document = new APLDocument(
434
            mainTemplate: $mainTemplate,
435
            layouts: ['TimeLayout' => $layout]
436
        );
437
438
        $this->assertInstanceOf(Bind::class, $document->layouts['TimeLayout']->bind[0]);
439
        $this->assertEquals('currentTime', $document->layouts['TimeLayout']->bind[0]->name);
440
        $this->assertEquals(BindType::STRING, $document->layouts['TimeLayout']->bind[0]->type);
441
    }
442
443
    public function testAPLDocumentComplexIntegration(): void
444
    {
445
        // Create a comprehensive APL document with multiple features
446
        $mainTemplate = new MainTemplate(
447
            parameters: ['payload', 'datasource'],
448
            items: []
449
        );
450
451
        $environment = new Environment(
452
            lang: 'en-US',
453
            layoutDirection: LayoutDirection::LTR
454
        );
455
456
        $settings = new Settings(
457
            idleTimeout: 60000,
458
            supportsResizing: true
459
        );
460
461
        $resource = new Resource(
462
            colors: ['primaryColor' => '#0066CC'],
463
            dimensions: ['headerHeight' => '100dp']
464
        );
465
466
        $document = new APLDocument(
467
            mainTemplate: $mainTemplate,
468
            type: 'APL',
469
            version: '2024.3',
470
            description: 'Complex integration test document',
471
            environment: $environment,
472
            settings: $settings,
473
            resources: [$resource],
474
            theme: 'auto'
475
        );
476
477
        $json = $document->jsonSerialize();
478
479
        $this->assertEquals('Complex integration test document', $json['description']);
480
        $this->assertInstanceOf(Environment::class, $json['environment']);
481
        $this->assertInstanceOf(Settings::class, $json['settings']);
482
        $this->assertCount(1, $json['resources']);
483
        $this->assertEquals('auto', $json['theme']);
484
    }
485
}
486