Skip to content

Commit 8bb62e4

Browse files
authored
Merge branch 'main' into feat/process
2 parents ff353fc + cf504ad commit 8bb62e4

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1846
-295
lines changed

.github/workflows/create-gh-release.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ jobs:
2323
id: generate_release_notes
2424
with:
2525
args: -v --latest --strip header
26+
env:
27+
GITHUB_REPO: ${{ github.repository }}
2628

2729
- name: Clean up release notes
2830
run: |

packages/cryptography/tests/Encryption/EncryptionTest.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,13 @@
1313
use Tempest\Cryptography\Signing\SigningAlgorithm;
1414
use Tempest\Cryptography\Signing\SigningConfig;
1515
use Tempest\Cryptography\Tests\CreatesSigner;
16+
use Tempest\Cryptography\Tests\HasMoreIntegerAssertions;
1617
use Tempest\DateTime\Duration;
1718

1819
final class EncryptionTest extends TestCase
1920
{
2021
use CreatesSigner;
22+
use HasMoreIntegerAssertions;
2123

2224
private function createEncrypter(?string $key = null, false|Duration $minimumExecutionDuration = false): GenericEncrypter
2325
{
@@ -60,8 +62,7 @@ public function test_time_protection(): void
6062
$this->assertSame('important data', $encrypter->decrypt($encrypted));
6163
$elapsed = microtime(true) - $start;
6264

63-
$this->assertGreaterThanOrEqual(0.29, $elapsed);
64-
$this->assertLessThanOrEqual(0.311, $elapsed);
65+
$this->assertEqualsToMoreOrLess(0.3, $elapsed, margin: 0.015);
6566
}
6667

6768
public function test_wrong_key(): void
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<?php
2+
3+
namespace Tempest\Cryptography\Tests;
4+
5+
use PHPUnit\Framework\ExpectationFailedException;
6+
7+
trait HasMoreIntegerAssertions
8+
{
9+
private function assertEqualsToMoreOrLess(int|float $expected, int|float $actual, int|float $margin): void
10+
{
11+
try {
12+
$this->assertGreaterThanOrEqual($expected - $margin, $actual);
13+
$this->assertLessThanOrEqual($expected + $margin, $actual);
14+
} catch (ExpectationFailedException $e) {
15+
throw new ExpectationFailedException(
16+
message: sprintf('Expected value to be within %s of %s, but got %s', $margin, $expected, $actual),
17+
comparisonFailure: $e->getComparisonFailure(),
18+
);
19+
}
20+
}
21+
}

packages/cryptography/tests/Signing/SignerTest.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@
22

33
namespace Tempest\Cryptography\Tests\Signing;
44

5+
use PHPUnit\Framework\ExpectationFailedException;
56
use PHPUnit\Framework\TestCase;
67
use Tempest\Clock\MockClock;
78
use Tempest\Cryptography\Signing\Exceptions\SigningKeyWasInvalid;
89
use Tempest\Cryptography\Signing\SigningAlgorithm;
910
use Tempest\Cryptography\Signing\SigningConfig;
1011
use Tempest\Cryptography\Tests\CreatesSigner;
12+
use Tempest\Cryptography\Tests\HasMoreIntegerAssertions;
1113
use Tempest\DateTime\Duration;
1214

1315
final class SignerTest extends TestCase
1416
{
1517
use CreatesSigner;
18+
use HasMoreIntegerAssertions;
1619

1720
public function test_good_signature(): void
1821
{
@@ -163,8 +166,7 @@ public function test_time_protection(): void
163166
$this->assertTrue($signer->verify($data, $signature));
164167
$elapsed = microtime(true) - $start;
165168

166-
$this->assertGreaterThanOrEqual(0.29, $elapsed);
167-
$this->assertLessThanOrEqual(0.311, $elapsed);
169+
$this->assertEqualsToMoreOrLess(0.3, $elapsed, margin: 0.015);
168170
}
169171

170172
public function test_time_protection_with_mock_clock(): void
@@ -182,7 +184,6 @@ public function test_time_protection_with_mock_clock(): void
182184
$this->assertTrue($signer->verify($data, $signature));
183185
$elapsed = $clock->timestamp()->getMilliseconds() - $ms;
184186

185-
$this->assertLessThanOrEqual(1_001, $elapsed);
186-
$this->assertGreaterThanOrEqual(999, $elapsed);
187+
$this->assertEqualsToMoreOrLess(1000, $elapsed, margin: 10);
187188
}
188189
}

packages/cryptography/tests/TimelockTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
final class TimelockTest extends TestCase
1313
{
14+
use HasMoreIntegerAssertions;
15+
1416
public function test_callback_is_executed(): void
1517
{
1618
$clock = new GenericClock();
@@ -29,8 +31,7 @@ public function test_locks_for_duration(): void
2931

3032
$elapsed = microtime(true) - $start;
3133

32-
$this->assertGreaterThanOrEqual(0.1, $elapsed, 'The timelock did not wait for the specified duration.');
33-
$this->assertLessThan(0.2, $elapsed, 'The timelock waited for too long.');
34+
$this->assertEqualsToMoreOrLess(0.1, $elapsed, margin: 0.015);
3435
}
3536

3637
public function test_return_early(): void
@@ -62,7 +63,7 @@ public function test_throws_exception_after_delay(): void
6263
);
6364
} catch (\RuntimeException) {
6465
$elapsed = microtime(true) - $start;
65-
$this->assertGreaterThanOrEqual(0.1, $elapsed, 'The exception was thrown before the timelock duration elapsed.');
66+
$this->assertEqualsToMoreOrLess(0.1, $elapsed, margin: 0.015);
6667
}
6768
}
6869

packages/database/src/Builder/ModelInspector.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Tempest\Database\Relation;
1313
use Tempest\Database\Table;
1414
use Tempest\Database\Virtual;
15+
use Tempest\Mapper\SerializeAs;
1516
use Tempest\Mapper\SerializeWith;
1617
use Tempest\Reflection\ClassReflector;
1718
use Tempest\Reflection\PropertyReflector;
@@ -149,7 +150,11 @@ public function getBelongsTo(string $name): ?BelongsTo
149150
return null;
150151
}
151152

152-
if ($property->hasAttribute(SerializeWith::class) || $property->getType()->asClass()->haSAttribute(SerializeWith::class)) {
153+
if ($property->hasAttribute(SerializeWith::class) || $property->getType()->asClass()->hasAttribute(SerializeWith::class)) {
154+
return null;
155+
}
156+
157+
if ($property->getType()->asClass()->hasAttribute(SerializeAs::class)) {
153158
return null;
154159
}
155160

packages/database/src/Builder/QueryBuilders/CountQueryBuilder.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
use function Tempest\Database\model;
1616

1717
/**
18-
* @template TModelClass of object
19-
* @implements \Tempest\Database\Builder\QueryBuilders\BuildsQuery<TModelClass>
20-
* @uses \Tempest\Database\Builder\QueryBuilders\HasWhereQueryBuilderMethods<TModelClass>
18+
* @template T of object
19+
* @implements \Tempest\Database\Builder\QueryBuilders\BuildsQuery<T>
20+
* @uses \Tempest\Database\Builder\QueryBuilders\HasWhereQueryBuilderMethods<T>
2121
*/
2222
final class CountQueryBuilder implements BuildsQuery
2323
{
@@ -29,11 +29,11 @@ final class CountQueryBuilder implements BuildsQuery
2929

3030
private ModelInspector $model;
3131

32-
public function __construct(
33-
/** @var class-string<TModelClass>|string|TModelClass $model */
34-
string|object $model,
35-
?string $column = null,
36-
) {
32+
/**
33+
* @param class-string<T>|string|T $model
34+
*/
35+
public function __construct(string|object $model, ?string $column = null)
36+
{
3737
$this->model = model($model);
3838

3939
$this->count = new CountStatement(
@@ -47,7 +47,7 @@ public function execute(mixed ...$bindings): int
4747
return $this->build()->fetchFirst(...$bindings)[$this->count->getKey()];
4848
}
4949

50-
/** @return self<TModelClass> */
50+
/** @return self<T> */
5151
public function distinct(): self
5252
{
5353
if ($this->count->column === null || $this->count->column === '*') {
@@ -59,7 +59,7 @@ public function distinct(): self
5959
return $this;
6060
}
6161

62-
/** @return self<TModelClass> */
62+
/** @return self<T> */
6363
public function bind(mixed ...$bindings): self
6464
{
6565
$this->bindings = [...$this->bindings, ...$bindings];

packages/database/src/Builder/QueryBuilders/DeleteQueryBuilder.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,11 @@ final class DeleteQueryBuilder implements BuildsQuery
2626

2727
private ModelInspector $model;
2828

29-
public function __construct(
30-
/** @var class-string<TModelClass>|string|TModelClass $model */
31-
string|object $model,
32-
) {
29+
/**
30+
* @param class-string<TModelClass>|string|TModelClass $model
31+
*/
32+
public function __construct(string|object $model)
33+
{
3334
$this->model = model($model);
3435
$this->delete = new DeleteStatement($this->model->getTableDefinition());
3536
}

packages/database/src/Builder/QueryBuilders/InsertQueryBuilder.php

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717

1818
use function Tempest\Database\model;
1919

20+
/**
21+
* @template T of object
22+
* @implements \Tempest\Database\Builder\QueryBuilders\BuildsQuery<T>
23+
*/
2024
final class InsertQueryBuilder implements BuildsQuery
2125
{
2226
use HasConditions, OnDatabase;
@@ -29,8 +33,10 @@ final class InsertQueryBuilder implements BuildsQuery
2933

3034
private ModelInspector $model;
3135

36+
/**
37+
* @param class-string<T>|string|T $model
38+
*/
3239
public function __construct(
33-
/** @var class-string|string $model */
3440
string|object $model,
3541
private readonly array $rows,
3642
private readonly SerializerFactory $serializerFactory,

packages/database/src/Builder/QueryBuilders/QueryBuilder.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,21 @@
77
use function Tempest\get;
88
use function Tempest\Support\arr;
99

10+
/**
11+
* @template T of object
12+
*/
1013
final readonly class QueryBuilder
1114
{
15+
/**
16+
* @param class-string<T>|string|T $model
17+
*/
1218
public function __construct(
1319
private string|object $model,
1420
) {}
1521

22+
/**
23+
* @return SelectQueryBuilder<T>
24+
*/
1625
public function select(string ...$columns): SelectQueryBuilder
1726
{
1827
return new SelectQueryBuilder(
@@ -21,6 +30,9 @@ public function select(string ...$columns): SelectQueryBuilder
2130
);
2231
}
2332

33+
/**
34+
* @return InsertQueryBuilder<T>
35+
*/
2436
public function insert(mixed ...$values): InsertQueryBuilder
2537
{
2638
if (! array_is_list($values)) {
@@ -34,6 +46,9 @@ public function insert(mixed ...$values): InsertQueryBuilder
3446
);
3547
}
3648

49+
/**
50+
* @return UpdateQueryBuilder<T>
51+
*/
3752
public function update(mixed ...$values): UpdateQueryBuilder
3853
{
3954
return new UpdateQueryBuilder(
@@ -43,11 +58,17 @@ public function update(mixed ...$values): UpdateQueryBuilder
4358
);
4459
}
4560

61+
/**
62+
* @return DeleteQueryBuilder<T>
63+
*/
4664
public function delete(): DeleteQueryBuilder
4765
{
4866
return new DeleteQueryBuilder($this->model);
4967
}
5068

69+
/**
70+
* @return CountQueryBuilder<T>
71+
*/
5172
public function count(?string $column = null): CountQueryBuilder
5273
{
5374
return new CountQueryBuilder(

0 commit comments

Comments
 (0)