Completed
Push — v2 ( 58f91a...3b3087 )
by Joschi
05:06
created

ItemTest::convertPropertyListToArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 8
c 0
b 0
f 0
cc 2
eloc 5
nc 2
nop 1
rs 9.4285
1
<?php
2
3
/**
4
 * micrometa
5
 *
6
 * @category Jkphl
7
 * @package Jkphl\Micrometa
8
 * @subpackage Jkphl\Micrometa\Tests
9
 * @author Joschi Kuphal <[email protected]> / @jkphl
10
 * @copyright Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
11
 * @license http://opensource.org/licenses/MIT The MIT License (MIT)
12
 */
13
14
/***********************************************************************************
15
 *  The MIT License (MIT)
16
 *
17
 *  Copyright © 2017 Joschi Kuphal <[email protected]> / @jkphl
18
 *
19
 *  Permission is hereby granted, free of charge, to any person obtaining a copy of
20
 *  this software and associated documentation files (the "Software"), to deal in
21
 *  the Software without restriction, including without limitation the rights to
22
 *  use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
23
 *  the Software, and to permit persons to whom the Software is furnished to do so,
24
 *  subject to the following conditions:
25
 *
26
 *  The above copyright notice and this permission notice shall be included in all
27
 *  copies or substantial portions of the Software.
28
 *
29
 *  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
30
 *  IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
31
 *  FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
32
 *  COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
33
 *  IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
34
 *  CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
35
 ***********************************************************************************/
36
37
namespace Jkphl\Micrometa\Tests\Domain;
38
39
use Jkphl\Micrometa\Application\Value\StringValue;
40
use Jkphl\Micrometa\Domain\Item\Item;
41
use Jkphl\Micrometa\Domain\Item\PropertyListInterface;
42
use Jkphl\Micrometa\Domain\Value\ValueInterface;
43
44
/**
45
 * Item tests
46
 *
47
 * @package Jkphl\Micrometa
48
 * @subpackage Jkphl\Micrometa\Tests
49
 */
50
class ItemTest extends \PHPUnit_Framework_TestCase
51
{
52
    /**
53
     * Public function test the item creation
54
     *
55
     * @param string|array $type Item type(s)
56
     * @param array $properties Item properties
57
     * @param $itemId Item id
58
     * @param array $expectedTypes Expected item types
59
     * @param array $expectedProperties Expected item properties
60
     * @param string $expectedId Expected item id
61
     * @dataProvider creationArgumentProvider
62
     */
63
    public function testItemCreation(
64
        $type,
65
        array $properties,
66
        $itemId,
67
        array $expectedTypes,
68
        array $expectedProperties,
69
        $expectedId
70
    ) {
71
        $item = new Item($type, $properties, $itemId);
0 ignored issues
show
Bug introduced by
It seems like $type defined by parameter $type on line 64 can also be of type array; however, Jkphl\Micrometa\Domain\Item\Item::__construct() does only seem to accept string|object<stdClass>|...teger,object<stdClass>>, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
72
        $this->assertInstanceOf(Item::class, $item);
73
        $this->assertEquals($expectedTypes, $item->getType());
74
        $this->assertEquals($expectedProperties, $this->convertPropertyListToArray($item->getProperties()));
75
        $this->assertEquals($expectedId, $item->getId());
76
    }
77
78
    /**
79
     * Convert a property list to a plain array
80
     *
81
     * @param PropertyListInterface $propertyList Property list
82
     * @return array Property list array
83
     */
84
    protected function convertPropertyListToArray(PropertyListInterface $propertyList)
85
    {
86
        $propertyListValues = [];
87
        foreach ($propertyList as $iri => $values) {
88
            $propertyListValues[$iri->profile.$iri->name] = $values;
89
        }
90
        return $propertyListValues;
91
    }
92
93
    /**
94
     * Data provider for item creation tests
95
     *
96
     * @return array Item creation arguments
97
     */
98
    public function creationArgumentProvider()
99
    {
100
        $item = new Item('test');
101
        return [
102
            ['test', [], null, [$this->t('test')], [], null],
103
            [$this->t('test', 'a'), [], null, [$this->t('test', 'a')], [], null],
104
            [['test'], [], null, [$this->t('test')], [], null],
105
            [['test', 'lorem'], [], null, [$this->t('test'), $this->t('lorem')], [], null],
106
            [['test', '', 'lorem'], [], null, [$this->t('test'), $this->t('lorem')], [], null],
107
            [
108
                'test',
109
                [$this->p('name1', 'value1')],
110
                null,
111
                [$this->t('test')],
112
                ['name1' => [$this->s('value1')]],
113
                null
114
            ],
115
            [
116
                'test',
117
                [$this->p('name1', '')],
118
                null,
119
                [$this->t('test')],
120
                [],
121
                null
122
            ],
123
            [
124
                'test',
125
                [$this->p('name1', [])],
126
                null,
127
                [$this->t('test')],
128
                [],
129
                null
130
            ],
131
            [
132
                'test',
133
                [$this->p('name1', 'value1', 'profile1/')],
134
                null,
135
                [$this->t('test')],
136
                ['profile1/name1' => [$this->s('value1')]],
137
                null
138
            ],
139
            [
140
                'test',
141
                [$this->p('name1', 'value1')],
142
                null,
143
                [$this->t('test')],
144
                ['name1' => [$this->s('value1')]],
145
                null
146
            ],
147
            [
148
                'test',
149
                [$this->p('name1', 'value1'), $this->p('name1', 'value2')],
150
                null,
151
                [$this->t('test')],
152
                ['name1' => [$this->s('value1'), $this->s('value2')]],
153
                null
154
            ],
155
            [
156
                'test',
157
                [$this->p('name1', 'value1'), $this->p('name2', 'value2')],
158
                null,
159
                [$this->t('test')],
160
                ['name1' => [$this->s('value1')], 'name2' => [$this->s('value2')]],
161
                null
162
            ],
163
            [
164
                'test',
165
                [$this->p('name', [$item])],
166
                null,
167
                [$this->t('test')],
168
                ['name' => [$item]],
169
                null
170
            ],
171
            ['test', [], 'id', [$this->t('test')], [], 'id'],
172
        ];
173
    }
174
175
    /**
176
     * Create a type object
177
     *
178
     * @param string $n Type name
179
     * @param string $p Type profile
180
     * @return object Type object
181
     */
182
    protected function t($n, $p = '')
183
    {
184
        return (object)['profile' => $p, 'name' => $n];
185
    }
186
187
    /**
188
     * Create a property object
189
     *
190
     * @param string $n Property name
191
     * @param mixed $s Property value(s)
192
     * @param string $p Property profiles
193
     * @return object Property object
194
     */
195
    protected function p($n, $s, $p = '')
196
    {
197
        $values = array_map([$this, 's'], (array)$s);
198
        return (object)['profile' => $p, 'name' => $n, 'values' => $values];
199
    }
200
201
    /**
202
     * Create a string value
203
     *
204
     * @param string $s Value
205
     * @return ValueInterface String value
206
     */
207
    protected function s($s)
208
    {
209
        return ($s instanceof ValueInterface) ? $s : new StringValue($s);
210
    }
211
212
    /**
213
     * Test the item creation with an empty types list
214
     *
215
     * @expectedException \Jkphl\Micrometa\Domain\Exceptions\InvalidArgumentException
216
     * @expectedExceptionCode 1490814631
217
     */
218
    public function testEmptyTypesList()
219
    {
220
        new Item(null);
221
    }
222
223
    /**
224
     * Test the item creation with an empty types list
225
     *
226
     * @expectedException \Jkphl\Micrometa\Domain\Exceptions\InvalidArgumentException
227
     * @expectedExceptionCode 1488314667
228
     */
229
    public function testEmptyTypeName()
230
    {
231
        new Item('');
232
    }
233
234
    /**
235
     * Test the item creation with an empty property name
236
     *
237
     * @expectedException \Jkphl\Micrometa\Domain\Exceptions\InvalidArgumentException
238
     * @expectedExceptionCode 1488314921
239
     */
240
    public function testEmptyPropertyName()
241
    {
242
        new Item('type', [$this->p('', 'value')]);
0 ignored issues
show
Documentation introduced by
array($this->p('', 'value')) is of type array<integer,object,{"0":"object"}>, but the function expects a array<integer,array>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
243
    }
244
245
    /**
246
     * Test empty property value list
247
     *
248
     * @expectedException \Jkphl\Micrometa\Domain\Exceptions\InvalidArgumentException
249
     * @expectedExceptionCode 1490814554
250
     */
251
    public function testInvalidPropertyStructure()
252
    {
253
        new Item('type', [(object)['invalid' => 'structure']]);
254
    }
255
256
    /**
257
     * Test the item creation with an invalid property value
258
     *
259
     * @expectedException \Jkphl\Micrometa\Domain\Exceptions\InvalidArgumentException
260
     * @expectedExceptionCode 1488315339
261
     */
262
    public function testInvalidPropertyValue()
263
    {
264
        new Item('type', [(object)['profile' => '', 'name' => 'test', 'values' => [123]]]);
265
    }
266
267
    /**
268
     * Test the item creation with an invalid property value
269
     *
270
     * @expectedException \Jkphl\Micrometa\Domain\Exceptions\OutOfBoundsException
271
     * @expectedExceptionCode 1488315604
272
     */
273
    public function testUnknownPropertyName()
274
    {
275
        $item = new Item('type');
276
        $item->getProperty('name');
277
    }
278
279
    /**
280
     * Test the item property getter
281
     */
282
    public function testItemPropertyGetter()
283
    {
284
        $item = new Item('type', [$this->p('name', 123)]);
0 ignored issues
show
Documentation introduced by
array($this->p('name', 123)) is of type array<integer,object,{"0":"object"}>, but the function expects a array<integer,array>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
285
        $this->assertEquals([new StringValue('123')], $item->getProperty('name'));
286
    }
287
}
288