|
13 | 13 |
|
14 | 14 | use ArrayIterator;
|
15 | 15 | use BadMethodCallException;
|
16 |
| -use function hexdec; |
| 16 | +use Generator; |
| 17 | +use InvalidArgumentException; |
| 18 | +use IteratorAggregate; |
| 19 | +use function json_encode; |
| 20 | +use const JSON_THROW_ON_ERROR; |
| 21 | +use Laudis\Neo4j\Databags\Pair; |
17 | 22 | use Laudis\Neo4j\Types\CypherList;
|
18 | 23 | use Laudis\Neo4j\Types\CypherMap;
|
19 | 24 | use OutOfBoundsException;
|
@@ -144,180 +149,311 @@ public function testMap(): void
|
144 | 149 | {
|
145 | 150 | $filter = $this->map->map(static fn (string $i, string $x) => $i.':'.$x);
|
146 | 151 |
|
147 |
| - self::assertEquals(new CypherList(['A:x', 'B:y', 'C:z']), $filter); |
| 152 | + self::assertEquals(new CypherMap(['A' => 'A:x', 'B' => 'B:y', 'C' => 'C:z']), $filter); |
148 | 153 | }
|
149 | 154 |
|
150 | 155 | public function testReduce(): void
|
151 | 156 | {
|
152 |
| - $count = $this->map->reduce(static function (?int $initial, int $key, string $value) { |
153 |
| - return ($initial ?? 0) + $key * hexdec($value); |
| 157 | + $count = $this->map->reduce(static function (?int $initial, string $key, string $value) { |
| 158 | + return ($initial ?? 0) + ord($value) + ord($key); |
154 | 159 | }, 5);
|
155 | 160 |
|
156 |
| - self::assertEquals(5 + hexdec('B') + 2 * hexdec('C'), $count); |
| 161 | + self::assertEquals(5 + ord('A') + ord('x') + ord('B') + ord('y') + ord('C') + ord('z'), $count); |
157 | 162 | }
|
158 | 163 |
|
159 | 164 | public function testFind(): void
|
160 | 165 | {
|
| 166 | + self::assertFalse($this->map->find('A')); |
161 | 167 | self::assertFalse($this->map->find('X'));
|
162 |
| - self::assertEquals(0, $this->map->find('A')); |
163 |
| - self::assertEquals(1, $this->map->find('B')); |
164 |
| - self::assertEquals(2, $this->map->find('C')); |
| 168 | + self::assertEquals('C', $this->map->find('z')); |
| 169 | + self::assertEquals('B', $this->map->find('y')); |
| 170 | + self::assertEquals('A', $this->map->find('x')); |
165 | 171 | }
|
166 | 172 |
|
167 | 173 | public function testReversed(): void
|
168 | 174 | {
|
169 |
| - self::assertEquals(new CypherList(['C', 'B', 'A']), $this->map->reversed()); |
170 |
| - self::assertEquals(new CypherList(['A', 'B', 'C']), $this->map); |
171 |
| - self::assertEquals(new CypherList(['A', 'B', 'C']), $this->map->reversed()->reversed()); |
| 175 | + self::assertEquals(new CypherMap(['C' => 'z', 'B' => 'y', 'A' => 'x']), $this->map->reversed()); |
| 176 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z']), $this->map); |
| 177 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z']), $this->map->reversed()->reversed()); |
172 | 178 | }
|
173 | 179 |
|
174 | 180 | public function testSliceSingle(): void
|
175 | 181 | {
|
176 | 182 | $sliced = $this->map->slice(1, 1);
|
177 |
| - self::assertEquals(new CypherList(['B']), $sliced); |
| 183 | + self::assertEquals(new CypherMap(['B' => 'y']), $sliced); |
178 | 184 | }
|
179 | 185 |
|
180 | 186 | public function testSliceDouble(): void
|
181 | 187 | {
|
182 | 188 | $sliced = $this->map->slice(1, 2);
|
183 |
| - self::assertEquals(new CypherList(['B', 'C']), $sliced); |
| 189 | + self::assertEquals(new CypherMap(['B' => 'y', 'C' => 'z']), $sliced); |
184 | 190 | }
|
185 | 191 |
|
186 | 192 | public function testSliceAll(): void
|
187 | 193 | {
|
188 | 194 | $sliced = $this->map->slice(0, 3);
|
189 |
| - self::assertEquals(new CypherList(['A', 'B', 'C']), $sliced); |
| 195 | + self::assertEquals($this->map, $sliced); |
190 | 196 | }
|
191 | 197 |
|
192 | 198 | public function testSliceTooMuch(): void
|
193 | 199 | {
|
194 | 200 | $sliced = $this->map->slice(0, 5);
|
195 |
| - self::assertEquals(new CypherList(['A', 'B', 'C']), $sliced); |
| 201 | + self::assertEquals($this->map, $sliced); |
196 | 202 | }
|
197 | 203 |
|
198 | 204 | public function testSliceEmpty(): void
|
199 | 205 | {
|
200 | 206 | $sliced = $this->map->slice(0, 0);
|
201 |
| - self::assertEquals(new CypherList(), $sliced); |
| 207 | + self::assertEquals(new CypherMap(), $sliced); |
202 | 208 | }
|
203 | 209 |
|
204 | 210 | public function testGetValid(): void
|
205 | 211 | {
|
206 |
| - self::assertEquals('A', $this->map->get(0)); |
207 |
| - self::assertEquals('B', $this->map->get(1)); |
208 |
| - self::assertEquals('C', $this->map->get(2)); |
| 212 | + self::assertEquals('x', $this->map->get('A')); |
| 213 | + self::assertEquals('y', $this->map->get('B')); |
| 214 | + self::assertEquals('z', $this->map->get('C')); |
| 215 | + } |
| 216 | + |
| 217 | + public function testGetDefault(): void |
| 218 | + { |
| 219 | + self::assertEquals('x', $this->map->get('A', null)); |
| 220 | + self::assertNull($this->map->get('x', null)); |
| 221 | + self::assertEquals(new stdClass(), $this->map->get('Cd', new stdClass())); |
209 | 222 | }
|
210 | 223 |
|
211 | 224 | public function testFirst(): void
|
212 | 225 | {
|
213 |
| - self::assertEquals('A', $this->map->first()); |
| 226 | + self::assertEquals(new Pair('A', 'x'), $this->map->first()); |
214 | 227 | }
|
215 | 228 |
|
216 | 229 | public function testFirstInvalid(): void
|
217 | 230 | {
|
218 | 231 | $this->expectException(OutOfBoundsException::class);
|
219 |
| - $this->expectExceptionMessage('Cannot grab first element of an empty list'); |
220 |
| - (new CypherList())->first(); |
| 232 | + $this->expectExceptionMessage('Cannot grab first element of an empty map'); |
| 233 | + (new CypherMap())->first(); |
221 | 234 | }
|
222 | 235 |
|
223 | 236 | public function testLast(): void
|
224 | 237 | {
|
225 |
| - self::assertEquals('C', $this->map->last()); |
| 238 | + self::assertEquals(new Pair('C', 'z'), $this->map->last()); |
226 | 239 | }
|
227 | 240 |
|
228 | 241 | public function testLastInvalid(): void
|
229 | 242 | {
|
230 | 243 | $this->expectException(OutOfBoundsException::class);
|
231 |
| - $this->expectExceptionMessage('Cannot grab last element of an empty list'); |
232 |
| - (new CypherList())->last(); |
| 244 | + $this->expectExceptionMessage('Cannot grab last element of an empty map'); |
| 245 | + (new CypherMap())->last(); |
233 | 246 | }
|
234 | 247 |
|
235 | 248 | public function testGetInvalid(): void
|
236 | 249 | {
|
237 | 250 | $this->expectException(OutOfBoundsException::class);
|
238 |
| - $this->expectExceptionMessage('Cannot get item in sequence at position: 3'); |
239 |
| - $this->map->get(3); |
240 |
| - } |
241 |
| - |
242 |
| - public function testGetNegative(): void |
243 |
| - { |
244 |
| - $this->expectException(OutOfBoundsException::class); |
245 |
| - $this->expectExceptionMessage('Cannot get item in sequence at position: -1'); |
246 |
| - $this->map->get(-1); |
| 251 | + $this->expectExceptionMessage('Cannot get item in sequence with key: a'); |
| 252 | + $this->map->get('a'); |
247 | 253 | }
|
248 | 254 |
|
249 | 255 | public function testIteration(): void
|
250 | 256 | {
|
251 | 257 | $counter = 0;
|
252 | 258 | foreach ($this->map as $key => $item) {
|
253 | 259 | ++$counter;
|
254 |
| - self::assertEquals(['A', 'B', 'C'][$key], $item); |
| 260 | + self::assertEquals(['A' => 'x', 'B' => 'y', 'C' => 'z'][$key], $item); |
255 | 261 | }
|
256 | 262 | self::assertEquals(3, $counter);
|
257 | 263 | }
|
258 | 264 |
|
259 | 265 | public function testIterationEmpty(): void
|
260 | 266 | {
|
261 | 267 | $counter = 0;
|
262 |
| - foreach ((new CypherList()) as $key => $item) { |
| 268 | + foreach ((new CypherMap()) as $key => $item) { |
263 | 269 | ++$counter;
|
264 |
| - self::assertEquals(['A', 'B', 'C'][$key], $item); |
| 270 | + self::assertEquals(['A' => 'x'][$key], $item); |
265 | 271 | }
|
266 | 272 | self::assertEquals(0, $counter);
|
267 | 273 | }
|
268 | 274 |
|
269 | 275 | public function testOffsetSet(): void
|
270 | 276 | {
|
271 | 277 | $this->expectException(BadMethodCallException::class);
|
272 |
| - $this->expectExceptionMessage('Laudis\Neo4j\Types\CypherList is immutable'); |
| 278 | + $this->expectExceptionMessage('Laudis\Neo4j\Types\CypherMap is immutable'); |
273 | 279 |
|
274 |
| - $this->map[0] = 'a'; |
| 280 | + $this->map['A'] = 'a'; |
275 | 281 | }
|
276 | 282 |
|
277 | 283 | public function testOffsetUnset(): void
|
278 | 284 | {
|
279 | 285 | $this->expectException(BadMethodCallException::class);
|
280 |
| - $this->expectExceptionMessage('Laudis\Neo4j\Types\CypherList is immutable'); |
| 286 | + $this->expectExceptionMessage('Laudis\Neo4j\Types\CypherMap is immutable'); |
281 | 287 |
|
282 |
| - unset($this->map[0]); |
| 288 | + unset($this->map['A']); |
283 | 289 | }
|
284 | 290 |
|
285 | 291 | public function testOffsetGetValid(): void
|
286 | 292 | {
|
287 |
| - self::assertEquals('A', $this->map[0]); |
288 |
| - self::assertEquals('B', $this->map[1]); |
289 |
| - self::assertEquals('C', $this->map[2]); |
| 293 | + self::assertEquals('x', $this->map['A']); |
| 294 | + self::assertEquals('y', $this->map['B']); |
| 295 | + self::assertEquals('z', $this->map['C']); |
290 | 296 | }
|
291 | 297 |
|
292 | 298 | public function testOffsetGetInvalid(): void
|
293 | 299 | {
|
294 | 300 | $this->expectException(OutOfBoundsException::class);
|
295 |
| - $this->expectExceptionMessage('Offset: "3" does not exists in object of instance: Laudis\Neo4j\Types\CypherList'); |
296 |
| - $this->map[3]; |
| 301 | + $this->expectExceptionMessage('Offset: "AA" does not exists in object of instance: Laudis\Neo4j\Types\CypherMap'); |
| 302 | + $this->map['AA']; |
| 303 | + } |
| 304 | + |
| 305 | + public function testIssetValid(): void |
| 306 | + { |
| 307 | + self::assertTrue(isset($this->map['A'])); |
| 308 | + self::assertTrue(isset($this->map['B'])); |
| 309 | + self::assertTrue(isset($this->map['C'])); |
| 310 | + } |
| 311 | + |
| 312 | + public function testIssetInValid(): void |
| 313 | + { |
| 314 | + self::assertFalse(isset($this->map['a'])); |
| 315 | + } |
| 316 | + |
| 317 | + public function testIssetValidNull(): void |
| 318 | + { |
| 319 | + self::assertTrue(isset((new CypherMap(['a' => null]))['a'])); |
| 320 | + } |
| 321 | + |
| 322 | + public function testJsonSerialize(): void |
| 323 | + { |
| 324 | + self::assertEquals('{"A":"x","B":"y","C":"z"}', json_encode($this->map, JSON_THROW_ON_ERROR)); |
| 325 | + } |
| 326 | + |
| 327 | + public function testJsonSerializeEmpty(): void |
| 328 | + { |
| 329 | + self::assertEquals('{}', json_encode(new CypherMap(), JSON_THROW_ON_ERROR)); |
| 330 | + } |
| 331 | + |
| 332 | + public function testJoin(): void |
| 333 | + { |
| 334 | + self::assertEquals('x;y;z', $this->map->join(';')); |
| 335 | + } |
| 336 | + |
| 337 | + public function testJoinEmpty(): void |
| 338 | + { |
| 339 | + self::assertEquals('', (new CypherMap())->join('A')); |
| 340 | + } |
| 341 | + |
| 342 | + public function testDiff(): void |
| 343 | + { |
| 344 | + $subtract = new CypherMap(['B' => null, 'Z' => 'z']); |
| 345 | + $result = $this->map->diff($subtract); |
| 346 | + |
| 347 | + self::assertEquals(new CypherMap(['A' => 'x', 'C' => 'z']), $result); |
| 348 | + self::assertEquals(new CypherMap(['B' => null, 'Z' => 'z']), $subtract); |
| 349 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z']), $this->map); |
| 350 | + } |
| 351 | + |
| 352 | + public function testDiffEmpty(): void |
| 353 | + { |
| 354 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z']), $this->map->diff([])); |
297 | 355 | }
|
298 | 356 |
|
299 |
| - public function testOffsetGetNegative(): void |
| 357 | + public function testIntersect(): void |
| 358 | + { |
| 359 | + $intersect = new CypherMap(['B' => null, 'Z' => 'z']); |
| 360 | + $result = $this->map->intersect($intersect); |
| 361 | + |
| 362 | + self::assertEquals(new CypherMap(['B' => 'y']), $result); |
| 363 | + self::assertEquals(new CypherMap(['B' => null, 'Z' => 'z']), $intersect); |
| 364 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z']), $this->map); |
| 365 | + } |
| 366 | + |
| 367 | + public function testUnion(): void |
| 368 | + { |
| 369 | + $intersect = new CypherMap(['B' => null, 'Z' => 'z']); |
| 370 | + $result = $this->map->union($intersect); |
| 371 | + |
| 372 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z', 'Z' => 'z']), $result); |
| 373 | + self::assertEquals(new CypherMap(['B' => null, 'Z' => 'z']), $intersect); |
| 374 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z']), $this->map); |
| 375 | + } |
| 376 | + |
| 377 | + public function testXor(): void |
| 378 | + { |
| 379 | + $intersect = new CypherMap(['B' => null, 'Z' => 'z']); |
| 380 | + $result = $this->map->xor($intersect); |
| 381 | + |
| 382 | + self::assertEquals(new CypherMap(['A' => 'x', 'C' => 'z', 'Z' => 'z']), $result); |
| 383 | + self::assertEquals(new CypherMap(['B' => null, 'Z' => 'z']), $intersect); |
| 384 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z']), $this->map); |
| 385 | + } |
| 386 | + |
| 387 | + public function testValue(): void |
| 388 | + { |
| 389 | + self::assertEquals(new CypherList(['x', 'y', 'z']), $this->map->values()); |
| 390 | + } |
| 391 | + |
| 392 | + public function testKeys(): void |
| 393 | + { |
| 394 | + self::assertEquals(new CypherList(['A', 'B', 'C']), $this->map->keys()); |
| 395 | + } |
| 396 | + |
| 397 | + public function testPairs(): void |
| 398 | + { |
| 399 | + $list = new CypherList([new Pair('A', 'x'), new Pair('B', 'y'), new Pair('C', 'z')]); |
| 400 | + self::assertEquals($list, $this->map->pairs()); |
| 401 | + } |
| 402 | + |
| 403 | + public function testSkip(): void |
| 404 | + { |
| 405 | + self::assertEquals(new Pair('A', 'x'), $this->map->skip(0)); |
| 406 | + self::assertEquals(new Pair('B', 'y'), $this->map->skip(1)); |
| 407 | + self::assertEquals(new Pair('C', 'z'), $this->map->skip(2)); |
| 408 | + } |
| 409 | + |
| 410 | + public function testSkipInvalid(): void |
300 | 411 | {
|
301 | 412 | $this->expectException(OutOfBoundsException::class);
|
302 |
| - $this->expectExceptionMessage('Offset: "-1" does not exists in object of instance: Laudis\Neo4j\Types\CypherList'); |
303 |
| - $this->map[-1]; |
| 413 | + $this->expectExceptionMessage('Cannot skip to a pair at position: 4'); |
| 414 | + self::assertEquals(new Pair('A', 'x'), $this->map->skip(4)); |
304 | 415 | }
|
305 | 416 |
|
306 |
| - public function testIssetValid(): void |
| 417 | + public function testInvalidConstruct(): void |
307 | 418 | {
|
308 |
| - self::assertTrue(isset($this->map[0])); |
309 |
| - self::assertTrue(isset($this->map[1])); |
310 |
| - self::assertTrue(isset($this->map[2])); |
| 419 | + $this->expectException(InvalidArgumentException::class); |
| 420 | + $this->expectExceptionMessage('Iterable must have a stringable keys'); |
| 421 | + |
| 422 | + new CypherMap(new class() implements IteratorAggregate { |
| 423 | + public function getIterator(): Generator |
| 424 | + { |
| 425 | + yield new stdClass() => 'x'; |
| 426 | + } |
| 427 | + }); |
311 | 428 | }
|
312 | 429 |
|
313 |
| - public function testIssetInValid(): void |
| 430 | + public function testSortedDefault(): void |
314 | 431 | {
|
315 |
| - self::assertFalse(isset($this->map[-1])); |
316 |
| - self::assertFalse(isset($this->map[3])); |
| 432 | + self::assertEquals($this->map, $this->map->sorted()); |
| 433 | + self::assertEquals($this->map, $this->map->reversed()->sorted()); |
317 | 434 | }
|
318 | 435 |
|
319 |
| - public function testIssetValidNull(): void |
| 436 | + public function testSortedCustom(): void |
320 | 437 | {
|
321 |
| - self::assertTrue(isset((new CypherList([null]))[0])); |
| 438 | + $sorted = $this->map->sorted(static fn (string $x, $y) => -1 * ($x <=> $y)); |
| 439 | + |
| 440 | + self::assertEquals(new CypherMap(['C' => 'z', 'B' => 'y', 'A' => 'x']), $sorted); |
| 441 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z']), $this->map); |
322 | 442 | }
|
| 443 | + |
| 444 | + public function testKSorted(): void |
| 445 | + { |
| 446 | + self::assertEquals($this->map, $this->map->ksorted()); |
| 447 | + self::assertEquals($this->map, $this->map->reversed()->ksorted()); |
| 448 | + } |
| 449 | + |
| 450 | + public function testKSortedCustom(): void |
| 451 | + { |
| 452 | + $sorted = $this->map->ksorted(static fn (string $x, $y) => -1 * ($x <=> $y)); |
| 453 | + |
| 454 | + self::assertEquals(new CypherMap(['C' => 'z', 'B' => 'y', 'A' => 'x']), $sorted); |
| 455 | + self::assertEquals(new CypherMap(['A' => 'x', 'B' => 'y', 'C' => 'z']), $this->map); |
| 456 | + } |
| 457 | + |
| 458 | + //test sorted and ksorted |
323 | 459 | }
|
0 commit comments