Skip to content

Commit 498b50b

Browse files
committed
feat(assert): Add CompositeRecord;
All chained assertions are nested now
1 parent f1ea084 commit 498b50b

File tree

15 files changed

+194
-41
lines changed

15 files changed

+194
-41
lines changed

src/Assert/Internal/Assertion/AssertArray.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use Testo\Assert\Internal\Assertion\Traits\IterableTrait;
99
use Testo\Assert\State\AssertException;
1010
use Testo\Assert\State\AssertTypeFailure;
11+
use Testo\Assert\State\AssertTypeSuccess;
1112
use Testo\Assert\StaticState;
1213
use Testo\Assert\Support;
1314

@@ -22,6 +23,7 @@ class AssertArray implements ArrayType
2223

2324
public function __construct(
2425
private readonly array $value,
26+
private readonly AssertTypeSuccess $parent,
2527
) {}
2628

2729
/**
@@ -35,8 +37,8 @@ public static function validateAndCreate(mixed $value): self
3537
{
3638
\is_array($value) or StaticState::fail(AssertTypeFailure::create('array', $value));
3739

38-
StaticState::log('Assert array: ' . Support::stringify($value));
39-
return new self($value);
40+
$parent = StaticState::typeSuccess('array', $value);
41+
return new self($value, $parent);
4042
}
4143

4244
/**

src/Assert/Internal/Assertion/AssertFloat.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Testo\Assert\Api\Builtin\FloatType;
88
use Testo\Assert\Internal\Assertion\Traits\NumericTrait;
99
use Testo\Assert\State\AssertTypeFailure;
10+
use Testo\Assert\State\AssertTypeSuccess;
1011
use Testo\Assert\StaticState;
1112
use Testo\Assert\Support;
1213

@@ -21,6 +22,7 @@ class AssertFloat implements FloatType
2122

2223
public function __construct(
2324
private readonly float $value,
25+
private readonly AssertTypeSuccess $parent,
2426
) {}
2527

2628
/**
@@ -34,7 +36,7 @@ public static function validateAndCreate(mixed $value): self
3436
{
3537
\is_float($value) or StaticState::fail(AssertTypeFailure::create('float', $value));
3638

37-
StaticState::log('Assert float: ' . Support::stringify($value));
38-
return new self($value);
39+
$parent = StaticState::typeSuccess('float', $value);
40+
return new self($value, $parent);
3941
}
4042
}

src/Assert/Internal/Assertion/AssertInt.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Testo\Assert\Api\Builtin\IntType;
88
use Testo\Assert\Internal\Assertion\Traits\NumericTrait;
99
use Testo\Assert\State\AssertTypeFailure;
10+
use Testo\Assert\State\AssertTypeSuccess;
1011
use Testo\Assert\StaticState;
1112
use Testo\Assert\Support;
1213

@@ -21,6 +22,7 @@ class AssertInt implements IntType
2122

2223
public function __construct(
2324
private readonly int $value,
25+
private readonly AssertTypeSuccess $parent,
2426
) {}
2527

2628
/**
@@ -34,7 +36,7 @@ public static function validateAndCreate(mixed $value): self
3436
{
3537
\is_int($value) or StaticState::fail(AssertTypeFailure::create('int', $value));
3638

37-
StaticState::log('Assert int: ' . Support::stringify($value));
38-
return new self($value);
39+
$parent = StaticState::typeSuccess('int', $value);
40+
return new self($value, $parent);
3941
}
4042
}

src/Assert/Internal/Assertion/AssertIterable.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Testo\Assert\Api\Builtin\IterableType;
88
use Testo\Assert\Internal\Assertion\Traits\IterableTrait;
99
use Testo\Assert\State\AssertTypeFailure;
10+
use Testo\Assert\State\AssertTypeSuccess;
1011
use Testo\Assert\StaticState;
1112
use Testo\Assert\Support;
1213

@@ -21,6 +22,7 @@ class AssertIterable implements IterableType
2122

2223
public function __construct(
2324
private readonly iterable $value,
25+
private readonly AssertTypeSuccess $parent,
2426
) {}
2527

2628
/**
@@ -34,7 +36,7 @@ public static function validateAndCreate(mixed $value): self
3436
{
3537
\is_iterable($value) or StaticState::fail(AssertTypeFailure::create('iterable', $value));
3638

37-
StaticState::log('Assert iterable: ' . Support::stringify($value));
38-
return new self($value);
39+
$parent = StaticState::typeSuccess('iterable', $value);
40+
return new self($value, $parent);
3941
}
4042
}

src/Assert/Internal/Assertion/AssertJson.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use Testo\Assert\Api\Json\JsonCommon;
1010
use Testo\Assert\Api\Json\JsonObject;
1111
use Testo\Assert\Api\Json\JsonStructure;
12+
use Testo\Assert\State\AssertTypeSuccess;
1213

1314
/**
1415
* Implementation of JSON assertions.
@@ -19,6 +20,7 @@ class AssertJson implements JsonAbstract
1920
{
2021
public function __construct(
2122
private mixed $value,
23+
private readonly AssertTypeSuccess $parent,
2224
) {}
2325

2426
/**

src/Assert/Internal/Assertion/AssertNumeric.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use Testo\Assert\Api\Builtin\IntType;
88
use Testo\Assert\Internal\Assertion\Traits\NumericTrait;
9+
use Testo\Assert\State\AssertTypeSuccess;
910

1011
/**
1112
* Assertion utilities for numeric data type.
@@ -18,5 +19,6 @@ class AssertNumeric implements IntType
1819

1920
public function __construct(
2021
public int|float $value,
22+
private readonly AssertTypeSuccess $parent,
2123
) {}
2224
}

src/Assert/Internal/Assertion/AssertObject.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Testo\Assert\Api\Builtin\ObjectType;
88
use Testo\Assert\State\AssertException;
99
use Testo\Assert\State\AssertTypeFailure;
10+
use Testo\Assert\State\AssertTypeSuccess;
1011
use Testo\Assert\StaticState;
1112
use Testo\Assert\Support;
1213

@@ -19,6 +20,7 @@ final class AssertObject implements ObjectType
1920
{
2021
public function __construct(
2122
private readonly object $value,
23+
private readonly AssertTypeSuccess $parent,
2224
) {}
2325

2426
/**
@@ -34,8 +36,8 @@ public static function validateAndCreate(mixed $value): self
3436
{
3537
\is_object($value) or StaticState::fail(AssertTypeFailure::create('object', $value));
3638

37-
StaticState::log('Assert object: ' . Support::stringify($value));
38-
return new self($value);
39+
$parent = StaticState::typeSuccess('object', $value);
40+
return new self($value, $parent);
3941
}
4042

4143
#[\Override]

src/Assert/Internal/Assertion/AssertString.php

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Testo\Assert\Api\Builtin\StringType;
88
use Testo\Assert\State\AssertException;
99
use Testo\Assert\State\AssertTypeFailure;
10+
use Testo\Assert\State\AssertTypeSuccess;
1011
use Testo\Assert\StaticState;
1112
use Testo\Assert\Support;
1213

@@ -19,6 +20,7 @@ class AssertString implements StringType
1920
{
2021
public function __construct(
2122
private readonly string $value,
23+
private readonly AssertTypeSuccess $parent,
2224
) {}
2325

2426
/**
@@ -33,8 +35,8 @@ public static function validateAndCreate(mixed $value): self
3335
{
3436
\is_string($value) or StaticState::fail(AssertTypeFailure::create('string', $value));
3537

36-
StaticState::log('Assert string: ' . Support::stringify($value));
37-
return new self($value);
38+
$parent = StaticState::typeSuccess('string', $value);
39+
return new self($value, $parent);
3840
}
3941

4042
/**

src/Assert/Internal/Assertion/Traits/IterableTrait.php

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@
55
namespace Testo\Assert\Internal\Assertion\Traits;
66

77
use Testo\Assert\State\AssertException;
8-
use Testo\Assert\StaticState;
8+
use Testo\Assert\State\AssertTypeSuccess;
99
use Testo\Assert\Support;
1010

1111
/**
1212
* Contains assertion methods for iterable values.
1313
*
1414
* @property iterable $value
15+
* @property AssertTypeSuccess $parent
1516
*/
1617
trait IterableTrait
1718
{
@@ -20,12 +21,12 @@ public function contains(mixed $needle, string $message = ''): self
2021
{
2122
foreach ($this->value as $item) {
2223
if ($item === $needle) {
23-
StaticState::log('Assert contains: ' . Support::stringify($needle) . '.');
24-
return new self($this->value);
24+
$this->parent->log('Assert contains: ' . Support::stringify($needle) . '.');
25+
return $this;
2526
}
2627
}
2728

28-
StaticState::fail(
29+
$this->parent->fail(
2930
AssertException::fail(
3031
\sprintf(
3132
'Failed to assert that %s contains %s.',
@@ -40,11 +41,11 @@ public function contains(mixed $needle, string $message = ''): self
4041
public function sameSizeAs(iterable $expected, string $message = ''): self
4142
{
4243
if (self::countIterable($this->value) === self::countIterable($expected)) {
43-
StaticState::log('Assert same size as: ' . Support::stringify($expected) . '.');
44-
return new self($this->value);
44+
$this->parent->log('Assert same size as: ' . Support::stringify($expected) . '.');
45+
return $this;
4546
}
4647

47-
StaticState::fail(
48+
$this->parent->fail(
4849
AssertException::fail(
4950
\sprintf(
5051
'Failed to assert that iterable %s has the same number of elements as %s.',
@@ -67,7 +68,7 @@ public function allOf(string $type, string $message = ''): self
6768
};
6869
foreach ($this->value as $element) {
6970
$actualType = \strtolower(\get_debug_type($element));
70-
$actualType === $type or StaticState::fail(
71+
$actualType === $type or $this->parent->fail(
7172
AssertException::fail(
7273
\sprintf(
7374
'Failed to assert that all elements of iterable %s have type %s (found %s instead).',
@@ -79,25 +80,25 @@ public function allOf(string $type, string $message = ''): self
7980
);
8081
}
8182

82-
StaticState::log(
83+
$this->parent->log(
8384
\sprintf(
8485
'Assert all elements are of type %s.',
8586
Support::stringify($type),
8687
),
8788
);
88-
return new self($this->value);
89+
return $this;
8990
}
9091

9192
#[\Override]
9293
public function hasCount(int $expected): self
9394
{
9495
$count = self::countIterable($this->value);
9596
if ($count === $expected) {
96-
StaticState::log("Assert count: {$count}.");
97-
return new self($this->value);
97+
$this->parent->log("Assert count: {$count}.");
98+
return $this;
9899
}
99100

100-
StaticState::fail(
101+
$this->parent->fail(
101102
AssertException::fail(
102103
\sprintf(
103104
'Failed to assert that %s has %d elements (found %d instead).',

src/Assert/Internal/Assertion/Traits/NumericTrait.php

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
namespace Testo\Assert\Internal\Assertion\Traits;
66

77
use Testo\Assert\State\AssertException;
8-
use Testo\Assert\StaticState;
8+
use Testo\Assert\State\AssertTypeSuccess;
99

1010
/**
1111
* Contains methods for comparing numeric values
1212
* @property int|float $value
13+
* @property AssertTypeSuccess $parent
1314
*/
1415
trait NumericTrait
1516
{
@@ -23,11 +24,11 @@ trait NumericTrait
2324
public function greaterThan(int|float $min, string $message = ''): self
2425
{
2526
if ($this->value > $min) {
26-
StaticState::log('Assert `' . $this->value . ' > ' . $min . '`', $message);
27+
$this->parent->log('Assert `' . $this->value . ' > ' . $min . '`', $message);
2728
return $this;
2829
}
2930

30-
StaticState::fail(AssertException::compare(
31+
$this->parent->fail(AssertException::compare(
3132
$min,
3233
$this->value,
3334
$message,
@@ -46,11 +47,11 @@ public function greaterThan(int|float $min, string $message = ''): self
4647
public function greaterThanOrEqual(int|float $min, string $message = ''): self
4748
{
4849
if ($this->value >= $min) {
49-
StaticState::log('Assert `' . $this->value . ' >= ' . $min . '`', $message);
50+
$this->parent->log('Assert `' . $this->value . ' >= ' . $min . '`', $message);
5051
return $this;
5152
}
5253

53-
StaticState::fail(AssertException::compare(
54+
$this->parent->fail(AssertException::compare(
5455
$min,
5556
$this->value,
5657
$message,
@@ -69,11 +70,11 @@ public function greaterThanOrEqual(int|float $min, string $message = ''): self
6970
public function lessThan(int|float $max, string $message = ''): self
7071
{
7172
if ($this->value < $max) {
72-
StaticState::log('Assert `' . $this->value . ' < ' . $max . '`', $message);
73+
$this->parent->log('Assert `' . $this->value . ' < ' . $max . '`', $message);
7374
return $this;
7475
}
7576

76-
StaticState::fail(AssertException::compare(
77+
$this->parent->fail(AssertException::compare(
7778
$max,
7879
$this->value,
7980
$message,
@@ -92,11 +93,11 @@ public function lessThan(int|float $max, string $message = ''): self
9293
public function lessThanOrEqual(int|float $max, string $message = ''): self
9394
{
9495
if ($this->value <= $max) {
95-
StaticState::log('Assert `' . $this->value . ' <= ' . $max . '`', $message);
96+
$this->parent->log('Assert `' . $this->value . ' <= ' . $max . '`', $message);
9697
return $this;
9798
}
9899

99-
StaticState::fail(AssertException::compare(
100+
$this->parent->fail(AssertException::compare(
100101
$max,
101102
$this->value,
102103
$message,

0 commit comments

Comments
 (0)