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

FlexSequenceComponentTest   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 182
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 95
c 1
b 0
f 1
dl 0
loc 182
rs 10
wmc 23

13 Methods

Rating   Name   Duplication   Size   Complexity  
A testConstructorWithAllParameters() 0 15 1
A testJsonSerializeWithDefaultNumbered() 0 6 1
A testConstructorWithDefaultParameters() 0 9 1
A testJsonSerializeWithEmptyOnScroll() 0 6 1
A testJsonSerializeWithAllProperties() 0 19 1
A testJsonSerializeWithNullValues() 0 10 1
A testExtendsAPLBaseComponent() 0 5 1
A testJsonSerializeWithNumberedTrue() 0 6 1
A testUsesMultiChildComponentTrait() 0 8 1
A testTypeConstant() 0 3 1
A testUsesActionableComponentTrait() 0 8 1
A testImplementsJsonSerializable() 0 5 1
B testJsonSerializeIncludesTraitProperties() 0 50 11
1
<?php
2
3
declare(strict_types=1);
4
5
namespace MaxBeckers\AmazonAlexa\Test\Response\Directives\APL\Component;
6
7
use MaxBeckers\AmazonAlexa\Request\ScrollDirection;
8
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Component\APLBaseComponent;
9
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Component\FlexSequenceComponent;
10
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Component\Traits\ActionableComponentTrait;
11
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Component\Traits\MultiChildComponentTrait;
12
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\APLComponentType;
13
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\FlexAlignItems;
14
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Document\Snap;
15
use MaxBeckers\AmazonAlexa\Response\Directives\APL\StandardCommand\AbstractStandardCommand;
16
use MaxBeckers\AmazonAlexa\Response\Directives\APL\Component\Action; // added
17
use PHPUnit\Framework\TestCase;
18
19
class FlexSequenceComponentTest extends TestCase
20
{
21
    public function testConstructorWithAllParameters(): void
22
    {
23
        $alignItems = FlexAlignItems::CENTER;
24
        $numbered = true;
25
        $onScroll = [$this->createMock(AbstractStandardCommand::class)];
26
        $scrollDirection = ScrollDirection::VERTICAL;
27
        $snap = Snap::START;
28
29
        $component = new FlexSequenceComponent($alignItems, $numbered, $onScroll, $scrollDirection, $snap);
30
31
        $this->assertSame($alignItems, $component->alignItems);
32
        $this->assertTrue($component->numbered);
33
        $this->assertSame($onScroll, $component->onScroll);
34
        $this->assertSame($scrollDirection, $component->scrollDirection);
35
        $this->assertSame($snap, $component->snap);
36
    }
37
38
    public function testConstructorWithDefaultParameters(): void
39
    {
40
        $component = new FlexSequenceComponent();
41
42
        $this->assertNull($component->alignItems);
43
        $this->assertFalse($component->numbered);
44
        $this->assertNull($component->onScroll);
45
        $this->assertNull($component->scrollDirection);
46
        $this->assertNull($component->snap);
47
    }
48
49
    public function testJsonSerializeWithAllProperties(): void
50
    {
51
        $alignItems = FlexAlignItems::END;
52
        $onScroll = [
53
            $this->createMock(AbstractStandardCommand::class),
54
            $this->createMock(AbstractStandardCommand::class),
55
        ];
56
        $scrollDirection = ScrollDirection::HORIZONTAL;
57
        $snap = Snap::CENTER;
58
59
        $component = new FlexSequenceComponent($alignItems, true, $onScroll, $scrollDirection, $snap);
60
        $result = $component->jsonSerialize();
61
62
        $this->assertSame(APLComponentType::FLEX_SEQUENCE->value, $result['type']);
63
        $this->assertSame($alignItems->value, $result['alignItems']);
64
        $this->assertTrue($result['numbered']);
65
        $this->assertSame($onScroll, $result['onScroll']);
66
        $this->assertSame($scrollDirection->value, $result['scrollDirection']);
67
        $this->assertSame($snap->value, $result['snap']);
68
    }
69
70
    public function testJsonSerializeWithDefaultNumbered(): void
71
    {
72
        $component = new FlexSequenceComponent();
73
        $result = $component->jsonSerialize();
74
75
        $this->assertArrayNotHasKey('numbered', $result);
76
    }
77
78
    public function testJsonSerializeWithNumberedTrue(): void
79
    {
80
        $component = new FlexSequenceComponent(numbered: true);
81
        $result = $component->jsonSerialize();
82
83
        $this->assertTrue($result['numbered']);
84
    }
85
86
    public function testJsonSerializeWithEmptyOnScroll(): void
87
    {
88
        $component = new FlexSequenceComponent(onScroll: []);
89
        $result = $component->jsonSerialize();
90
91
        $this->assertArrayNotHasKey('onScroll', $result);
92
    }
93
94
    public function testJsonSerializeWithNullValues(): void
95
    {
96
        $component = new FlexSequenceComponent();
97
        $result = $component->jsonSerialize();
98
99
        $this->assertSame(APLComponentType::FLEX_SEQUENCE->value, $result['type']);
100
        $this->assertArrayNotHasKey('alignItems', $result);
101
        $this->assertArrayNotHasKey('onScroll', $result);
102
        $this->assertArrayNotHasKey('scrollDirection', $result);
103
        $this->assertArrayNotHasKey('snap', $result);
104
    }
105
106
    public function testTypeConstant(): void
107
    {
108
        $this->assertSame(APLComponentType::FLEX_SEQUENCE, FlexSequenceComponent::TYPE);
109
    }
110
111
    public function testExtendsAPLBaseComponent(): void
112
    {
113
        $component = new FlexSequenceComponent();
114
115
        $this->assertInstanceOf(APLBaseComponent::class, $component);
116
    }
117
118
    public function testUsesActionableComponentTrait(): void
119
    {
120
        $component = new FlexSequenceComponent();
121
122
        $this->assertTrue(in_array(
123
            ActionableComponentTrait::class,
124
            class_uses($component),
125
            true
126
        ));
127
    }
128
129
    public function testUsesMultiChildComponentTrait(): void
130
    {
131
        $component = new FlexSequenceComponent();
132
133
        $this->assertTrue(in_array(
134
            MultiChildComponentTrait::class,
135
            class_uses($component),
136
            true
137
        ));
138
    }
139
140
    public function testImplementsJsonSerializable(): void
141
    {
142
        $component = new FlexSequenceComponent();
143
144
        $this->assertInstanceOf(\JsonSerializable::class, $component);
145
    }
146
147
    /**
148
     * Ensure every public property exposed by the actionable & multi child traits
149
     * (when present on FlexSequenceComponent) is serialized when populated.
150
     */
151
    public function testJsonSerializeIncludesTraitProperties(): void
152
    {
153
        $component = new FlexSequenceComponent();
154
155
        // Candidate properties from ActionableComponentTrait & MultiChildComponentTrait (and some common APL base actionable hooks).
156
        $candidates = [
157
            // Actionable / gesture / event related:
158
            'actions', 'action', 'gestures',
159
            'onMount', 'onPress', 'onLongPress',
160
            'onSwipe', 'onScroll', 'onCursorEnter', 'onCursorExit', 'onCursorMove',
161
            'onDown', 'onUp', 'onCancel',
162
            'handleTick', 'handleVisibilityChange',
163
            // Multi-child:
164
            'item', 'items',
165
        ];
166
167
        $expected = [];
168
169
        foreach ($candidates as $prop) {
170
            if (!property_exists($component, $prop)) {
171
                continue;
172
            }
173
174
            if ($prop === 'item') {
175
                $expected[$prop] = ['child' => 1];
176
            } elseif ($prop === 'items') {
177
                $expected[$prop] = [['child' => 1], ['child' => 2]];
178
            } elseif ($prop === 'gestures') {
179
                $expected[$prop] = [['type' => 'TestGesture']];
180
            } elseif ($prop === 'action') {                      // changed: single Action
181
                $expected[$prop] = $this->createMock(Action::class);
182
            } elseif ($prop === 'actions') {                     // changed: array of Actions
183
                $expected[$prop] = [$this->createMock(Action::class)];
184
            } elseif (str_starts_with($prop, 'on') || str_starts_with($prop, 'handle')) {
185
                $expected[$prop] = [$this->createMock(AbstractStandardCommand::class)];
186
            } else {
187
                $expected[$prop] = ['value'];
188
            }
189
190
            $component->$prop = $expected[$prop];
191
        }
192
193
        $json = $component->jsonSerialize();
194
195
        // Basic type assertion
196
        $this->assertSame(APLComponentType::FLEX_SEQUENCE->value, $json['type']);
197
198
        foreach ($expected as $prop => $value) {
199
            $this->assertArrayHasKey($prop, $json, "Property '$prop' was not serialized.");
200
            $this->assertSame($value, $json[$prop], "Mismatch for serialized property '$prop'.");
201
        }
202
    }
203
}
204