Skip to content

Commit 0f5ca7a

Browse files
committed
fix: Fix conditions according to example tests
1 parent 5bb6b3d commit 0f5ca7a

16 files changed

+219
-16
lines changed

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
"ext-mbstring": "*",
4444
"psr/log": "^1.1",
4545
"symfony/polyfill-php80": "^1.32",
46-
"symfony/yaml": "^5.4"
46+
"symfony/yaml": "^5.4",
47+
"symfony/polyfill-php81": "^1.33"
4748
},
4849
"require-dev": {
4950
"phpunit/phpunit": "^9",

composer.lock

Lines changed: 81 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Featurevisor\Datafile;
6+
7+
8+
final class AttributeException extends \LogicException
9+
{
10+
public static function createForNotFoundAttribute(string $name): self
11+
{
12+
return new self("Attribute '$name' not found");
13+
}
14+
15+
public static function createForInvalidType(string $attribute, array $allowedTypes, string $givenType): self
16+
{
17+
$allowedTypesMsg = implode(', ', $allowedTypes);
18+
return new self("Attribute '$attribute' expected one of '$allowedTypesMsg'. Given '$givenType'");
19+
}
20+
}

src/Datafile/Conditions.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ public function __construct(ConditionInterface $expression)
4444

4545
public function isSatisfiedBy(array $context): bool
4646
{
47-
return $this->expression->isSatisfiedBy($context);
47+
try {
48+
return $this->expression->isSatisfiedBy($context);
49+
} catch (AttributeException $e) {
50+
return false;
51+
}
4852
}
4953
}

src/Datafile/Conditions/AndCondition.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
namespace Featurevisor\Datafile\Conditions;
66

77

8+
use Featurevisor\Datafile\AttributeException;
9+
810
final class AndCondition implements ConditionInterface
911
{
1012
/** @var array<ConditionInterface> */
@@ -18,7 +20,11 @@ public function __construct(ConditionInterface ...$conditions)
1820
public function isSatisfiedBy(array $context): bool
1921
{
2022
foreach ($this->conditions as $condition) {
21-
if ($condition->isSatisfiedBy($context) === false) {
23+
try {
24+
if ($condition->isSatisfiedBy($context) === false) {
25+
return false;
26+
}
27+
} catch (AttributeException $e) {
2228
return false;
2329
}
2430
}

src/Datafile/Conditions/ConditionFactory.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ final class ConditionFactory
1212
{
1313
public function create(array $conditions): ConditionInterface
1414
{
15-
if (array_key_exists('attribute', $conditions)) {
16-
return $this->createCondition($conditions);
15+
if (array_is_list($conditions) === false) {
16+
return $this->map($conditions);
1717
}
1818

1919
$mappedConditions = array_map(fn ($condition) => $this->map($condition), $conditions);

src/Datafile/Conditions/ConditionInterface.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@
22

33
namespace Featurevisor\Datafile\Conditions;
44

5+
use Featurevisor\Datafile\AttributeException;
6+
57
interface ConditionInterface
68
{
9+
/**
10+
* @throws AttributeException
11+
*/
712
public function isSatisfiedBy(array $context): bool;
813
}

src/Datafile/Conditions/ContextLookup.php

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,46 @@
55
namespace Featurevisor\Datafile\Conditions;
66

77

8+
use Featurevisor\Datafile\AttributeException;
9+
810
trait ContextLookup
911
{
1012
/**
1113
* @return mixed|null
14+
* @throws AttributeException
1215
*/
1316
public function getValueFromContext(array $context, string $attribute)
1417
{
1518
if (strpos($attribute, '.') === false) {
16-
return $context[$attribute] ?? null;
19+
if (array_key_exists($attribute, $context) === false) {
20+
throw AttributeException::createForNotFoundAttribute($attribute);
21+
}
22+
23+
return $context[$attribute];
1724
}
1825

1926
$keys = explode('.', $attribute);
2027
$current = $context;
2128

2229
foreach ($keys as $key) {
23-
if (!is_array($current) || !isset($current[$key])) {
24-
return null;
30+
if (is_array($current) === false || array_key_exists($key, $current) === false) {
31+
throw AttributeException::createForNotFoundAttribute($attribute);
2532
}
2633
$current = $current[$key];
2734
}
2835

2936
return $current;
3037
}
38+
39+
/**
40+
* @param array<string> $allowedTypes
41+
* @param mixed $value
42+
* @throws AttributeException
43+
*/
44+
private function validateType(array $allowedTypes, string $attribute, $value): void
45+
{
46+
if ($value !== null && in_array(gettype($value), $allowedTypes, true) === false) {
47+
throw AttributeException::createForInvalidType($attribute, $allowedTypes, gettype($value));
48+
}
49+
}
3150
}

src/Datafile/Conditions/InCondition.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,13 @@
55
namespace Featurevisor\Datafile\Conditions;
66

77

8+
use Featurevisor\Datafile\AttributeException;
9+
810
final class InCondition implements ConditionInterface
911
{
1012
use ContextLookup;
1113

14+
private const ALLOWED_TYPES = ['string', 'integer'];
1215
private string $attribute;
1316
/** @var array<string> */
1417
private array $value;
@@ -30,6 +33,9 @@ public function __construct(string $attribute, array $value)
3033

3134
public function isSatisfiedBy(array $context): bool
3235
{
33-
return in_array($this->getValueFromContext($context, $this->attribute), $this->value, true);
36+
$valueFromContext = $this->getValueFromContext($context, $this->attribute);
37+
$this->validateType(self::ALLOWED_TYPES, $this->attribute, $valueFromContext);
38+
39+
return in_array($valueFromContext, $this->value, true);
3440
}
3541
}

src/Datafile/Conditions/NotCondition.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
namespace Featurevisor\Datafile\Conditions;
66

77

8+
use Featurevisor\Datafile\AttributeException;
9+
810
final class NotCondition implements ConditionInterface
911
{
1012
private ConditionInterface $specification;
@@ -16,6 +18,10 @@ public function __construct(ConditionInterface $specification)
1618

1719
public function isSatisfiedBy(array $context): bool
1820
{
19-
return $this->specification->isSatisfiedBy($context) === false;
21+
try {
22+
return $this->specification->isSatisfiedBy($context) === false;
23+
} catch (AttributeException $e) {
24+
return false;
25+
}
2026
}
2127
}

0 commit comments

Comments
 (0)