Passed
Push — html ( d230bc...4d98c2 )
by Peter
03:13
created

MultiSelectTest::testRender()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 5
c 1
b 0
f 0
nc 1
nop 8
dl 0
loc 17
rs 10

How to fix   Many Parameters   

Many Parameters

Methods with many parameters are not only hard to understand, but their parameters also often become inconsistent when you need more, or different data.

There are several approaches to avoid long parameter lists:

1
<?php
2
3
declare(strict_types=1);
4
5
namespace AbterPhp\Framework\Form\Element;
6
7
use AbterPhp\Framework\Constant\Html5;
8
use AbterPhp\Framework\Form\Component\Option;
9
use AbterPhp\Framework\Html\Attribute;
10
use AbterPhp\Framework\Html\Helper\Attributes;
11
use AbterPhp\Framework\TestDouble\Html\Component\StubAttributeFactory;
12
use AbterPhp\Framework\TestDouble\I18n\MockTranslatorFactory;
13
use InvalidArgumentException;
14
use PHPUnit\Framework\TestCase;
15
use stdClass;
16
17
class MultiSelectTest extends TestCase
18
{
19
    /**
20
     * @return array[]
21
     */
22
    public function renderProvider(): array
23
    {
24
        $attribs = StubAttributeFactory::createAttributes();
25
        $str     = Attributes::toString($attribs);
26
27
        return [
28
            'simple'               => [
29
                'abc',
30
                'bcd',
31
                ['val'],
32
                [],
33
                null,
34
                null,
35
                null,
36
                '<select multiple id="abc" name="bcd"></select>',
37
            ],
38
            'missing translations' => [
39
                'abc',
40
                'bcd',
41
                ['val'],
42
                [],
43
                null,
44
                [],
45
                null,
46
                '<select multiple id="abc" name="bcd"></select>',
47
            ],
48
            'extra attributes'     => [
49
                'abc',
50
                'bcd',
51
                ['val'],
52
                [],
53
                $attribs,
54
                [],
55
                null,
56
                "<select$str multiple id=\"abc\" name=\"bcd\"></select>",
57
            ],
58
            'options'              => [
59
                'abc',
60
                'bcd',
61
                ['val'],
62
                ['bde' => 'BDE', 'cef' => 'CEF'],
63
                $attribs,
64
                [],
65
                null,
66
                "<select$str multiple id=\"abc\" name=\"bcd\"><option value=\"bde\">BDE</option>\n<option value=\"cef\">CEF</option></select>", // phpcs:ignore
67
            ],
68
            'option selected'      => [
69
                'abc',
70
                'bcd',
71
                ['cef'],
72
                ['bde' => 'BDE', 'cef' => 'CEF'],
73
                $attribs,
74
                [],
75
                null,
76
                "<select$str multiple id=\"abc\" name=\"bcd\"><option value=\"bde\">BDE</option>\n<option value=\"cef\" selected>CEF</option></select>", // phpcs:ignore
77
            ],
78
        ];
79
    }
80
81
    /**
82
     * @dataProvider renderProvider
83
     *
84
     * @param string               $inputId
85
     * @param string               $name
86
     * @param string[]             $value
87
     * @param array<string,string> $options
88
     * @param Attribute[]|null     $attributes
89
     * @param string[]|null        $translations
90
     * @param string|null          $tag
91
     * @param string               $expectedResult
92
     */
93
    public function testRender(
94
        string $inputId,
95
        string $name,
96
        array $value,
97
        array $options,
98
        ?array $attributes,
99
        ?array $translations,
100
        ?string $tag,
101
        string $expectedResult
102
    ): void {
103
        $sut = $this->createMultiSelect($inputId, $name, $value, $options, $attributes, $translations, $tag);
104
105
        $actualResult   = (string)$sut;
106
        $repeatedResult = (string)$sut;
107
108
        $this->assertSame($expectedResult, $actualResult);
109
        $this->assertSame($actualResult, $repeatedResult);
110
    }
111
112
    public function testSetValueSetsOptionsSelected(): void
113
    {
114
        $sut = new MultiSelect('id', 'name');
115
116
        $option1 = new Option('1', 'foo', true);
117
        $option2 = new Option('2', 'bar', false);
118
        $option3 = new Option('3', 'baz', false);
119
120
        $sut->add($option1, $option2, $option3);
121
122
        $sut->setValue(['2', '3']);
123
124
        $this->assertStringNotContainsString(Html5::ATTR_SELECTED, (string)$option1);
125
        $this->assertStringContainsString(Html5::ATTR_SELECTED, (string)$option2);
126
        $this->assertStringContainsString(Html5::ATTR_SELECTED, (string)$option3);
127
    }
128
129
    /**
130
     * @return array
131
     */
132
    public function setValueFailureProvider(): array
133
    {
134
        return [
135
            'string'   => [''],
136
            'stdclass' => [new stdClass()],
137
            'int'      => [123],
138
            'bool'     => [false],
139
            'float'    => [123.53],
140
            'integers' => [[1, 3, 4]],
141
        ];
142
    }
143
144
    /**
145
     * @dataProvider setValueFailureProvider
146
     *
147
     * @param mixed $value
148
     */
149
    public function testSetValueThrowsExceptionOnInvalid($value): void
150
    {
151
        $this->expectException(InvalidArgumentException::class);
152
153
        $sut = new MultiSelect('id', 'foo');
154
155
        $sut->setValue($value);
156
    }
157
158
    public function testRemoveAttributeThrowsExceptionWhenTryingToRemoveProtectedAttributes(): void
159
    {
160
        $this->expectException(\RuntimeException::class);
161
162
        $sut = new MultiSelect('id', 'foo');
163
164
        $sut->removeAttribute(Html5::ATTR_NAME);
165
    }
166
167
    public function testGetName(): void
168
    {
169
        $expectedResult = 'foo';
170
171
        $sut = new MultiSelect('id', $expectedResult);
172
173
        $actualResult = $sut->getName();
174
175
        $this->assertEquals($expectedResult, $actualResult);
176
    }
177
178
    public function testGetGetValue(): void
179
    {
180
        $expectedResult = ['bar', 'ba'];
181
182
        $sut = $this->createMultiSelect('id', 'name', $expectedResult, ['foo' => 'Foo', 'bar' => 'Bar', 'ba' => 'Ba']);
183
184
        $actualResult = $sut->getValue();
185
186
        $this->assertEquals($expectedResult, $actualResult);
187
    }
188
189
    /**
190
     * @param string                       $inputId
191
     * @param string                       $name
192
     * @param string[]                     $values
193
     * @param array<string,string>         $options
194
     * @param array<string,Attribute>|null $attributes
195
     * @param string[]|null                $translations
196
     * @param string|null                  $tag
197
     *
198
     * @return MultiSelect
199
     */
200
    protected function createMultiSelect(
201
        string $inputId,
202
        string $name,
203
        array $values,
204
        array $options,
205
        ?array $attributes = null,
206
        ?array $translations = null,
207
        ?string $tag = null
208
    ): MultiSelect {
209
        $translatorMock = MockTranslatorFactory::createSimpleTranslator($this, $translations);
210
211
        $multiSelect = new MultiSelect($inputId, $name, [], $attributes, $tag);
212
213
        foreach ($options as $k => $v) {
214
            $multiSelect->add(new Option($k, $v, in_array($k, $values, true)));
215
        }
216
217
        $multiSelect->setTranslator($translatorMock);
218
219
        return $multiSelect;
220
    }
221
}
222