Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
26 / 26
n/a
0 / 0
CRAP
n/a
0 / 0
1<?php
2
3// ╔════════════════════════════════════════════════════════════╗
4// ║ MIT Licence (#Expat) - https://opensource.org/licenses/MIT ║
5// ║ Copyright 2026 Frederic Poeydomenge <dyno@phexium.com>     ║
6// ╚════════════════════════════════════════════════════════════╝
7
8declare(strict_types=1);
9
10use Phexium\Domain\Id\TimestampId;
11use Phexium\Domain\Specification\BinaryAndNotSpecification;
12use Tests\Phexium\Fake\Domain\Specification\IdSpecification as FakeIdSpecification;
13use Tests\Phexium\Fake\Domain\Specification\NameSpecification as FakeNameSpecification;
14
15test('toSql() combines two specifications with AND NOT operator', function (): void {
16    $nameSpec = new FakeNameSpecification('Foo');
17    $idSpec = new FakeIdSpecification(new TimestampId(123));
18    $andNotSpec = new BinaryAndNotSpecification($nameSpec, $idSpec);
19
20    $result = $andNotSpec->toSql();
21
22    expect($result)->toBeArray();
23    expect($result)->toHaveKey('sql');
24    expect($result)->toHaveKey('params');
25    expect($result['sql'])->toBe('(name = :name_0) AND NOT (id = :id_1)');
26    expect($result['params'])->toBe(['name_0' => 'Foo', 'id_1' => 123]);
27});
28
29test('toInMemoryFilter() returns callable that applies AND NOT logic', function (): void {
30    $nameSpec = new FakeNameSpecification('Foo');
31    $idSpec = new FakeIdSpecification(new TimestampId(123));
32    $andNotSpec = new BinaryAndNotSpecification($nameSpec, $idSpec);
33
34    $filter = $andNotSpec->toInMemoryFilter();
35
36    expect($filter)->toBeCallable();
37
38    $matchingBothRow = ['id' => 123, 'name' => 'Foo'];
39    expect($filter($matchingBothRow))->toBeFalse();
40
41    $matchingIdOnly = ['id' => 123, 'name' => 'Bar'];
42    expect($filter($matchingIdOnly))->toBeFalse();
43
44    $matchingNameOnly = ['id' => 456, 'name' => 'Foo'];
45    expect($filter($matchingNameOnly))->toBeTrue();
46
47    $matchingNone = ['id' => 456, 'name' => 'Bar'];
48    expect($filter($matchingNone))->toBeFalse();
49});