From 4839d01907b2e3df8c3a654edc4be9e2b819489c Mon Sep 17 00:00:00 2001 From: npldevfr Date: Mon, 29 Jan 2024 17:10:14 +0100 Subject: [PATCH] feat: conditions --- src/ConditionsBuilder.php | 89 +++++++++++--- src/Interfaces/ConditionsBuilderInterface.php | 55 +++++++++ tests/ConditionsBuilderTest.php | 114 +++++++++++++++++- 3 files changed, 240 insertions(+), 18 deletions(-) create mode 100644 src/Interfaces/ConditionsBuilderInterface.php diff --git a/src/ConditionsBuilder.php b/src/ConditionsBuilder.php index 38dfafa..384e8b8 100644 --- a/src/ConditionsBuilder.php +++ b/src/ConditionsBuilder.php @@ -3,9 +3,10 @@ namespace Npldevfr\Liquipedia; use Exception; +use Npldevfr\Liquipedia\Interfaces\ConditionsBuilderInterface; use Npldevfr\Liquipedia\Meta\Conditions; -final class ConditionsBuilder +final class ConditionsBuilder implements ConditionsBuilderInterface { private string $raw; @@ -14,14 +15,22 @@ public function __construct(?string $raw = null) $this->raw = $raw ?? ''; } - /** - * @throws Exception - */ - public static function build(string $key, string $operator, string $value): self - { - self::ensureValidOperator($operator); + public static function build( + ?string $key = null, + ?string $operator = null, + ?string $value = null + ): self { + if (is_null($key) && is_null($operator) && is_null($value)) { + return new self(); + } + + if (isset($key) && isset($operator) && isset($value)) { + self::ensureValidOperator($operator); - return new self("([[$key$operator$value]])"); + return new self("([[$key$operator$value]])"); + } + + throw new Exception('[LiquipediaBuilder] Invalid arguments, you have to set all or none of them.'); } /** @@ -45,16 +54,66 @@ public function and(string $key, string $operator, string $value): self return $this; } - // public function andMany(array $conditions): self - // { - // foreach ($conditions as $key => $condition) { - // $this->and($key, $condition[0], $condition[1]); - // } - // return $this; - // } + public function andManyAnd(string $key, string $operator, array $values): self + { + self::ensureValidOperator($operator); + + $raws = array_map(fn ($value): string => "[[$key$operator$value]]", $values); + + $this->raw .= ($this->isEmpty() ? '' : ' AND ').'('.implode(' AND ', $raws).')'; + + return $this; + } + + private function isEmpty(): bool + { + return $this->raw === ''; + } public function toValue(): string { return $this->raw; } + + public function andManyOr(string $key, string $operator, array $values): ConditionsBuilderInterface + { + self::ensureValidOperator($operator); + + $raws = array_map(fn ($value): string => "[[$key$operator$value]]", $values); + + $this->raw .= ($this->isEmpty() ? '' : ' AND ').'('.implode(' OR ', $raws).')'; + + return $this; + } + + public function or(string $key, string $operator, string $value): ConditionsBuilderInterface + { + self::ensureValidOperator($operator); + + $this->raw .= ' OR ([['.$key.$operator.$value.']])'; + + return $this; + } + + public function orManyAnd(string $key, string $operator, array $values): ConditionsBuilderInterface + { + self::ensureValidOperator($operator); + + $raws = array_map(fn ($value): string => "[[$key$operator$value]]", $values); + + $this->raw .= ($this->isEmpty() ? '' : ' OR ').'('.implode(' AND ', $raws).')'; + + return $this; + } + + public function orManyOr(string $key, string $operator, array $values): ConditionsBuilderInterface + { + self::ensureValidOperator($operator); + + $raws = array_map(fn ($value): string => "[[$key$operator$value]]", $values); + + $this->raw .= ($this->isEmpty() ? '' : ' OR ').'('.implode(' OR ', $raws).')'; + + return $this; + } } diff --git a/src/Interfaces/ConditionsBuilderInterface.php b/src/Interfaces/ConditionsBuilderInterface.php new file mode 100644 index 0000000..04608cb --- /dev/null +++ b/src/Interfaces/ConditionsBuilderInterface.php @@ -0,0 +1,55 @@ + $values + * + * @throws Exception + */ + public function andManyAnd(string $key, string $operator, array $values): self; + + /** + * @param array $values + * + * @throws Exception + */ + public function andManyOr(string $key, string $operator, array $values): self; + + /** + * @throws Exception + */ + public function or(string $key, string $operator, string $value): self; + + /** + * @param array $values + * + * @throws Exception + */ + public function orManyAnd(string $key, string $operator, array $values): self; + + /** + * @param array $values + * + * @throws Exception + */ + public function orManyOr(string $key, string $operator, array $values): self; + + public function toValue(): string; + + /** + * @throws Exception + */ + public static function build(?string $key = null, + ?string $operator = null, + ?string $value = null): self; +} diff --git a/tests/ConditionsBuilderTest.php b/tests/ConditionsBuilderTest.php index 1242237..fd1bd62 100644 --- a/tests/ConditionsBuilderTest.php +++ b/tests/ConditionsBuilderTest.php @@ -1,6 +1,7 @@ toValue()) ->toBe('([[my_key'.$condition.'my_value]])'); -})->with(\Npldevfr\Liquipedia\Meta\Conditions::all()); +})->with(Conditions::all()); -it('', function () { +it('can build with default constructor & and method', function () { expect( - ConditionsBuilder::build('build_key', '::!', 'build_value') + ConditionsBuilder::build('build_key', Conditions::NOT_EQUAL, 'build_value') ->and('my_key', '::', 'my_value') ->toValue() )->toBe('([[build_key::!build_value]]) AND ([[my_key::my_value]])'); }); + +it('can build without default constructor & andManyAnd method', function () { + $builder = ConditionsBuilder::build() + ->andManyAnd('my_key', '::', ['my_value', 'my_value2']); + + expect($builder->toValue()) + ->toBe('([[my_key::my_value]] AND [[my_key::my_value2]])'); + +}); + +it('can build with default constructor & andManyA d method', function () { + + expect( + ConditionsBuilder::build('build_key', Conditions::NOT_EQUAL, 'build_value') + ->andManyAnd('my_key', '::', ['my_value', 'my_value2']) + ->toValue() + )->toBe('([[build_key::!build_value]]) AND ([[my_key::my_value]] AND [[my_key::my_value2]])'); +}); + +it('can build with default constructor & andManyOr method', function () { + + expect( + ConditionsBuilder::build('build_key', Conditions::NOT_EQUAL, 'build_value') + ->andManyOr('my_key', '::', ['my_value', 'my_value2']) + ->toValue() + )->toBe('([[build_key::!build_value]]) AND ([[my_key::my_value]] OR [[my_key::my_value2]])'); +}); + +it('can build with default constructor & or method', function () { + + expect( + ConditionsBuilder::build('build_key', Conditions::NOT_EQUAL, 'build_value') + ->or('my_key', '::', 'my_value') + ->toValue() + )->toBe('([[build_key::!build_value]]) OR ([[my_key::my_value]])'); +}); + +it('can build with default constructor & orManyAnd method', function () { + + expect( + ConditionsBuilder::build('build_key', Conditions::NOT_EQUAL, 'build_value') + ->orManyAnd('my_key', '::', ['my_value', 'my_value2']) + ->toValue() + )->toBe('([[build_key::!build_value]]) OR ([[my_key::my_value]] AND [[my_key::my_value2]])'); +}); + +it('can build with default constructor & orManyOr method', function () { + + expect( + ConditionsBuilder::build('build_key', Conditions::NOT_EQUAL, 'build_value') + ->orManyOr('my_key', '::', ['my_value', 'my_value2']) + ->toValue() + )->toBe('([[build_key::!build_value]]) OR ([[my_key::my_value]] OR [[my_key::my_value2]])'); +}); + +it('can build with default constructor & andManyAnd method', function () { + + expect( + ConditionsBuilder::build('build_key', Conditions::NOT_EQUAL, 'build_value') + ->andManyAnd('my_key', '::', ['my_value', 'my_value2']) + ->toValue() + )->toBe('([[build_key::!build_value]]) AND ([[my_key::my_value]] AND [[my_key::my_value2]])'); +}); + +it('can build with default constructor & andManyAnd & orManyAnd methods', function () { + + $builder = ConditionsBuilder::build('build_key', '::!', 'build_value') + ->andManyAnd('my_key', '::', ['my_value', 'my_value2']) + ->orManyAnd('my_key2', '::', ['my_value', 'my_value2']); + + expect($builder->toValue()) + ->toBe('([[build_key::!build_value]]) AND ([[my_key::my_value]] AND [[my_key::my_value2]]) OR ([[my_key2::my_value]] AND [[my_key2::my_value2]])'); + +}); + +it('can build with default constructor & andManyAnd & orManyOr methods', function () { + + $builder = ConditionsBuilder::build('build_key', '::!', 'build_value') + ->andManyAnd('my_key', '::', ['my_value', 'my_value2']) + ->orManyOr('my_key2', '::', ['my_value', 'my_value2']); + + expect($builder->toValue()) + ->toBe('([[build_key::!build_value]]) AND ([[my_key::my_value]] AND [[my_key::my_value2]]) OR ([[my_key2::my_value]] OR [[my_key2::my_value2]])'); + +}); + +it('can build with default constructor & andManyOr & orManyAnd methods', function () { + + $builder = ConditionsBuilder::build('build_key', '::!', 'build_value') + ->andManyOr('my_key', '::', ['my_value', 'my_value2']) + ->orManyAnd('my_key2', '::', ['my_value', 'my_value2']); + + expect($builder->toValue()) + ->toBe('([[build_key::!build_value]]) AND ([[my_key::my_value]] OR [[my_key::my_value2]]) OR ([[my_key2::my_value]] AND [[my_key2::my_value2]])'); + +}); + +it('can build with default constructor & andManyOr & orManyOr methods', function () { + + $builder = ConditionsBuilder::build('build_key', '::!', 'build_value') + ->andManyOr('my_key', '::', ['my_value', 'my_value2']) + ->orManyOr('my_key2', '::', ['my_value', 'my_value2']); + + expect($builder->toValue()) + ->toBe('([[build_key::!build_value]]) AND ([[my_key::my_value]] OR [[my_key::my_value2]]) OR ([[my_key2::my_value]] OR [[my_key2::my_value2]])'); + +});