Skip to content

Commit 8d555ce

Browse files
authored
IBX-4918: Moved Specification abstraction from AdminUi to Core (#196)
For more details see https://issues.ibexa.co/browse/IBX-4918 or #196
1 parent 4a9ec46 commit 8d555ce

File tree

10 files changed

+283
-0
lines changed

10 files changed

+283
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Contracts\Core\Specification;
10+
11+
abstract class AbstractSpecification implements SpecificationInterface
12+
{
13+
abstract public function isSatisfiedBy($item): bool;
14+
15+
public function and(SpecificationInterface $other): SpecificationInterface
16+
{
17+
return new AndSpecification($this, $other);
18+
}
19+
20+
public function or(SpecificationInterface $other): SpecificationInterface
21+
{
22+
return new OrSpecification($this, $other);
23+
}
24+
25+
public function not(): SpecificationInterface
26+
{
27+
return new NotSpecification($this);
28+
}
29+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Contracts\Core\Specification;
10+
11+
final class AndSpecification extends AbstractSpecification
12+
{
13+
private SpecificationInterface $one;
14+
15+
private SpecificationInterface $two;
16+
17+
public function __construct(SpecificationInterface $one, SpecificationInterface $two)
18+
{
19+
$this->one = $one;
20+
$this->two = $two;
21+
}
22+
23+
public function isSatisfiedBy($item): bool
24+
{
25+
return $this->one->isSatisfiedBy($item) && $this->two->isSatisfiedBy($item);
26+
}
27+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Contracts\Core\Specification;
10+
11+
final class NotSpecification extends AbstractSpecification
12+
{
13+
private SpecificationInterface $specification;
14+
15+
public function __construct(SpecificationInterface $specification)
16+
{
17+
$this->specification = $specification;
18+
}
19+
20+
public function isSatisfiedBy($item): bool
21+
{
22+
return !$this->specification->isSatisfiedBy($item);
23+
}
24+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Contracts\Core\Specification;
10+
11+
final class OrSpecification extends AbstractSpecification
12+
{
13+
private SpecificationInterface $one;
14+
15+
private SpecificationInterface $two;
16+
17+
public function __construct(SpecificationInterface $one, SpecificationInterface $two)
18+
{
19+
$this->one = $one;
20+
$this->two = $two;
21+
}
22+
23+
public function isSatisfiedBy($item): bool
24+
{
25+
return $this->one->isSatisfiedBy($item) || $this->two->isSatisfiedBy($item);
26+
}
27+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Contracts\Core\Specification;
10+
11+
interface SpecificationInterface
12+
{
13+
/**
14+
* @param mixed $item
15+
*/
16+
public function isSatisfiedBy($item): bool;
17+
18+
public function and(SpecificationInterface $other): SpecificationInterface;
19+
20+
public function or(SpecificationInterface $other): SpecificationInterface;
21+
22+
public function not(): SpecificationInterface;
23+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
declare(strict_types=1);
8+
9+
namespace Ibexa\Tests\Core\Specification;
10+
11+
class AbstractSpecificationTest extends BaseSpecificationTest
12+
{
13+
public function testSpecification(): void
14+
{
15+
$isStringSpecification = $this->getIsStringSpecification();
16+
$isTestStringSpecification = $this->getIsTestStringSpecification();
17+
18+
self::assertTrue($isStringSpecification->isSatisfiedBy('test_string'));
19+
self::assertFalse($isStringSpecification->isSatisfiedBy(1234));
20+
}
21+
22+
public function testSpecificationAnd(): void
23+
{
24+
$isStringSpecification = $this->getIsStringSpecification();
25+
$isTestStringSpecification = $this->getIsTestStringSpecification();
26+
27+
self::assertTrue($isStringSpecification->and($isTestStringSpecification)->isSatisfiedBy('test'));
28+
self::assertFalse($isStringSpecification->and($isTestStringSpecification)->isSatisfiedBy('test_string'));
29+
self::assertFalse($isStringSpecification->and($isTestStringSpecification)->isSatisfiedBy(1234));
30+
}
31+
32+
public function testSpecificationOr(): void
33+
{
34+
$isStringSpecification = $this->getIsStringSpecification();
35+
$isTestStringSpecification = $this->getIsTestStringSpecification();
36+
37+
self::assertTrue($isStringSpecification->or($isTestStringSpecification)->isSatisfiedBy('test'));
38+
self::assertTrue($isStringSpecification->or($isTestStringSpecification)->isSatisfiedBy('test_string'));
39+
self::assertFalse($isStringSpecification->or($isTestStringSpecification)->isSatisfiedBy(1234));
40+
}
41+
42+
public function testSpecificationNot(): void
43+
{
44+
$isStringSpecification = $this->getIsStringSpecification();
45+
46+
self::assertFalse($isStringSpecification->not()->isSatisfiedBy('test_string'));
47+
self::assertTrue($isStringSpecification->not()->isSatisfiedBy(1234));
48+
}
49+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
namespace Ibexa\Tests\Core\Specification;
8+
9+
use Ibexa\Contracts\Core\Specification\AndSpecification;
10+
11+
class AndSpecificationTest extends BaseSpecificationTest
12+
{
13+
public function testAndSpecification(): void
14+
{
15+
$andSpecification = new AndSpecification(
16+
$this->getIsStringSpecification(),
17+
$this->getIsTestStringSpecification()
18+
);
19+
20+
self::assertTrue($andSpecification->isSatisfiedBy('test'));
21+
self::assertFalse($andSpecification->isSatisfiedBy('test_string'));
22+
self::assertFalse($andSpecification->isSatisfiedBy(1234));
23+
}
24+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
namespace Ibexa\Tests\Core\Specification;
8+
9+
use Ibexa\Contracts\Core\Specification\AbstractSpecification;
10+
use Ibexa\Contracts\Core\Specification\SpecificationInterface;
11+
use PHPUnit\Framework\TestCase;
12+
13+
abstract class BaseSpecificationTest extends TestCase
14+
{
15+
protected function getIsStringSpecification(): SpecificationInterface
16+
{
17+
return new class() extends AbstractSpecification {
18+
public function isSatisfiedBy($item): bool
19+
{
20+
return is_string($item);
21+
}
22+
};
23+
}
24+
25+
protected function getIsTestStringSpecification(): SpecificationInterface
26+
{
27+
return new class() extends AbstractSpecification {
28+
public function isSatisfiedBy($item): bool
29+
{
30+
return $item === 'test';
31+
}
32+
};
33+
}
34+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
namespace Ibexa\Tests\Core\Specification;
8+
9+
use Ibexa\Contracts\Core\Specification\NotSpecification;
10+
11+
class NotSpecificationTest extends BaseSpecificationTest
12+
{
13+
public function testNotSpecification(): void
14+
{
15+
$andSpecification = new NotSpecification(
16+
$this->getIsStringSpecification()
17+
);
18+
19+
self::assertFalse($andSpecification->isSatisfiedBy('test'));
20+
self::assertTrue($andSpecification->isSatisfiedBy(1234));
21+
}
22+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?php
2+
3+
/**
4+
* @copyright Copyright (C) Ibexa AS. All rights reserved.
5+
* @license For full copyright and license information view LICENSE file distributed with this source code.
6+
*/
7+
namespace Ibexa\Tests\Core\Specification;
8+
9+
use Ibexa\Contracts\Core\Specification\OrSpecification;
10+
11+
class OrSpecificationTest extends BaseSpecificationTest
12+
{
13+
public function testOrSpecification(): void
14+
{
15+
$andSpecification = new OrSpecification(
16+
$this->getIsStringSpecification(),
17+
$this->getIsTestStringSpecification()
18+
);
19+
20+
self::assertTrue($andSpecification->isSatisfiedBy('test'));
21+
self::assertTrue($andSpecification->isSatisfiedBy('test_string'));
22+
self::assertFalse($andSpecification->isSatisfiedBy(1234));
23+
}
24+
}

0 commit comments

Comments
 (0)