Issues (5)

tests/LinqCollectionTest.php (1 issue)

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