Completed
Push — master ( 96b143...a1ff80 )
by Chad
14s queued 11s
created

LinqCollectionTest::chainSkipTakeAndCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 1
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
1
<?php
2
3
namespace SubjectivePHPTest\Linq;
4
5
use ArrayIterator;
6
use PHPUnit\Framework\TestCase;
7
use StdClass;
8
use SubjectivePHP\Linq\LinqCollection;
9
10
/**
11
 * @coversDefaultClass \SubjectivePHP\Linq\LinqCollection
12
 * @covers ::__construct
13
 * @covers ::getIterator
14
 * @covers ::<private>
15
 */
16
final class LinqCollectionTest extends TestCase
17
{
18
    /**
19
     * @var LinqCollection
20
     */
21
    private $collection;
22
23
    /**
24
     * Prepare each test.
25
     */
26
    public function setUp()
27
    {
28
        $data = json_decode(file_get_contents(__DIR__ . '/books.json'));
29
        $this->collection = LinqCollection::from(new ArrayIterator($data));
30
    }
31
32
    /**
33
     * @test
34
     * @covers ::from
35
     */
36
    public function collectionCanBeCreatedFromIterator()
37
    {
38
        $array = json_decode(file_get_contents(__DIR__ . '/books.json'), true);
39
        $collection = LinqCollection::from(new ArrayIterator($array));
40
        $this->assertSame($array, iterator_to_array($collection));
41
    }
42
43
    /**
44
     * @test
45
     * @covers ::from
46
     */
47
    public function collectionCanBeCreatedFromArray()
48
    {
49
        $array = json_decode(file_get_contents(__DIR__ . '/books.json'), true);
50
        $collection = LinqCollection::from($array);
51
        $this->assertSame($array, iterator_to_array($collection));
52
    }
53
54
    /**
55
     * @test
56
     * @covers ::from
57
     * @expectedException \InvalidArgumentException
58
     */
59
    public function collectionCannotBeConstructedWithString()
60
    {
61
        LinqCollection::from('abcd');
0 ignored issues
show
Bug introduced by
'abcd' of type string is incompatible with the type Traversable|array expected by parameter $collection of SubjectivePHP\Linq\LinqCollection::from(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

61
        LinqCollection::from(/** @scrutinizer ignore-type */ 'abcd');
Loading history...
62
    }
63
64
    /**
65
     * @test
66
     * @covers ::first
67
     * @expectedException \SubjectivePHP\Linq\InvalidOperationException
68
     */
69
    public function cannotCallFirstOnEmptyCollection()
70
    {
71
        $collection = LinqCollection::from([]);
72
        $collection->first();
73
    }
74
75
    /**
76
     * @test
77
     * @covers ::first
78
     */
79
    public function firstReturnsFirstElement()
80
    {
81
        $first = $this->collection->first();
82
        $this->assertSame('58339e95d5200', $first->id);
83
    }
84
85
    /**
86
     * @test
87
     * @covers ::firstOrDefault
88
     */
89
    public function firstReturnsDefaultIfEmpty()
90
    {
91
        $default = new \StdClass();
92
        $callable = function ($element) {
0 ignored issues
show
Unused Code introduced by
The parameter $element is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

92
        $callable = function (/** @scrutinizer ignore-unused */ $element) {

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
93
            return false;
94
        };
95
        $this->assertSame($default, $this->collection->firstOrDefault($callable, $default));
96
    }
97
98
    /**
99
     * @test
100
     * @covers ::count
101
     */
102
    public function countReturnsCountOfElementsInSequence()
103
    {
104
        $this->assertSame(11, $this->collection->count());
105
    }
106
107
    /**
108
     * @test
109
     * @covers ::orderBy
110
     */
111
    public function orderByOrdersSequence()
112
    {
113
        $collection = LinqCollection::from(['z', 'g', 'a', 'n']);
114
        $callable = function ($a, $b) {
115
            return strcmp($a, $b);
116
        };
117
118
        $this->assertSame(
119
            [2 => 'a', 1 => 'g', 3 => 'n', 0 => 'z'],
120
            iterator_to_array($collection->orderBy($callable))
121
        );
122
    }
123
124
    /**
125
     * @test
126
     * @covers ::skip
127
     * @covers ::take
128
     */
129
    public function skipAndTake()
130
    {
131
        $result = $this->collection->skip(2)->take(1);
132
133
        $this->assertEquals(
134
            [
135
                2 => (object)[
136
                    "author" => "Corets, Eva",
137
                    "title" => "Maeve Ascendant",
138
                    "genre" => "Fantasy",
139
                    "price" => 5.95,
140
                    "published" => 974437200,
141
                    "description" => 'After the collapse of a nanotechnology society in England, the young survivors '
142
                    . 'lay the foundation for a new society.',
143
                    "id" => "58339e95d526f"
144
                ],
145
            ],
146
            iterator_to_array($result)
147
        );
148
    }
149
150
    /**
151
     * @test
152
     */
153
    public function chainSkipTakeAndCount()
154
    {
155
        $this->assertSame(1, $this->collection->skip(3)->take(1)->count());
156
    }
157
158
    /**
159
     * @test
160
     */
161
    public function largeChain()
162
    {
163
        $actual = $this->collection->where(
164
            function (StdClass $book) : bool {
165
                return $book->genre === 'Computer';
166
            }
167
        )->select(
168
            function (StdClass $book) : array {
169
                return [
170
                    'id' => $book->id,
171
                    'title' => $book->title,
172
                    'salePrice' => round($book->price * 0.90, 2),
173
                ];
174
            }
175
        )->orderBy(
176
            function (array $thisBook, array $thatBook) : int {
177
                if ($thisBook['salePrice'] === $thatBook['salePrice']) {
178
                    return 0;
179
                }
180
181
                return ($thisBook['salePrice'] > $thatBook['salePrice']) ? 1 : -1;
182
            }
183
        )->skip(2)->take(1)->first();
184
185
        $expected = [
186
            'id' => '58339e95d5200',
187
            'title' => "XML Developer's Guide",
188
             'salePrice' => 40.46,
189
        ];
190
191
        $this->assertSame($actual, $expected);
192
    }
193
194
    /**
195
     * @test
196
     * @covers ::where
197
     */
198
    public function whereFilters()
199
    {
200
        $callable = function (StdClass $book) : bool {
201
            return $book->genre === 'Romance';
202
        };
203
204
        $result = $this->collection->where($callable);
205
206
        $this->assertEquals(
207
            [
208
                5 => (object)[
209
                    "author" => "Randall, Cynthia",
210
                    "title" => "Lover Birds",
211
                    "genre" => "Romance",
212
                    "price" => 4.95,
213
                    "published" => 967867200,
214
                    "description" => 'When Carla meets Paul at an ornithology conference, tempers fly as feathers get'
215
                    . ' ruffled.',
216
                    "id" => "58339e95d530e"
217
                ],
218
                6 => (object)[
219
                    "author" => "Thurman, Paula",
220
                    "title" => "Splish Splash",
221
                    "genre" => "Romance",
222
                    "price" => 4.95,
223
                    "published" => 973141200,
224
                    "description" => "A deep sea diver finds true love twenty thousand leagues beneath the sea.",
225
                    "id" => "58339e95d5343"
226
                ]
227
            ],
228
            iterator_to_array($result)
229
        );
230
    }
231
232
    /**
233
     * @test
234
     * @covers ::select
235
     */
236
    public function select()
237
    {
238
        $callable = function (StdClass $book) : array {
239
            return [
240
                'id' => $book->id,
241
                'genre' => $book->genre,
242
            ];
243
        };
244
245
        $result = $this->collection->select($callable);
246
        $this->assertSame(
247
            [
248
                ['id' => '58339e95d5200', 'genre' => 'Computer'],
249
                ['id' => '58339e95d5239', 'genre' => 'Fantasy'],
250
                ['id' => '58339e95d526f', 'genre' => 'Fantasy'],
251
                ['id' => '58339e95d52a4', 'genre' => 'Fantasy'],
252
                ['id' => '58339e95d52d9', 'genre' => 'Fantasy'],
253
                ['id' => '58339e95d530e', 'genre' => 'Romance'],
254
                ['id' => '58339e95d5343', 'genre' => 'Romance'],
255
                ['id' => '58339e95d5378', 'genre' => 'Horror'],
256
                ['id' => '58339e95d53ae', 'genre' => 'Science Fiction'],
257
                ['id' => '58339e95d53e4', 'genre' => 'Computer'],
258
                ['id' => '58339e95d5419', 'genre' => 'Computer'],
259
            ],
260
            iterator_to_array($result)
261
        );
262
    }
263
}
264