Skip to content

Commit 147b977

Browse files
committed
Improve test suite
1 parent de77d4d commit 147b977

File tree

4 files changed

+37
-23
lines changed

4 files changed

+37
-23
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ All Notable changes to `bakame/http-strucured-fields` will be documented in this
1616
- methods `getByKey`, `hasKeys`, `indexByKey`, `keyByIndex`, `toAssociative` to all ordered map classes (`Dictionary` and `Parameters`).
1717
- `StructuredFieldProvider` interface
1818
- `Item::parameterByKey` and `Item::parameterByIndex` methods to mirror the new public API.
19-
- `Item::tryNew` which returns `null` instead of throwing an exception
19+
- `Item::tryNew` and `Item::tryFromPair` which return `null` instead of throwing an exception
2020
- `Parameters::valueByKey`
2121
- `Parameters::valueByIndex`
2222
- Added a validation mechanism to facilitate `Item` and `Parameters` validation against field definition.

src/Item.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,18 @@ public static function fromAssociative(
7979
return new self(new Value($value), $parameters);
8080
}
8181

82+
/**
83+
* @param array{0: SfItemInput, 1?: Parameters|iterable<array{0:string, 1:SfItemInput}>}|array<mixed> $pair
84+
*/
85+
public static function tryFromPair(array $pair): ?self
86+
{
87+
try {
88+
return self::fromPair($pair);
89+
} catch (StructuredFieldError) {
90+
return null;
91+
}
92+
}
93+
8294
/**
8395
* @param array{0: SfItemInput, 1?: Parameters|iterable<array{0:string, 1:SfItemInput}>}|array<mixed> $pair
8496
*

tests/Record.php

Lines changed: 23 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,24 @@
1717
* can_fail?: bool,
1818
* expected?: array,
1919
* }
20-
* @phpstan-type itemValue array{__type:string, value:int|string}|string|bool|int|float|null
20+
* @phpstan-type CustomValueType array{
21+
* __type: 'binary'|'date'|'displaystring'|'token',
22+
* value: int|string
23+
* }
24+
* @phpstan-type ItemValue CustomValueType|string|bool|int|float|null
2125
*/
2226
final class Record
2327
{
2428
private function __construct(
2529
public readonly string $name,
26-
/** @var 'dictionary'|'list'|'item' */
27-
public readonly string $type,
30+
public readonly DataType $type,
2831
/** @var array<string> */
2932
public readonly array $raw,
3033
/** @var array<string> */
3134
public readonly array $canonical,
3235
public readonly bool $mustFail,
3336
public readonly bool $canFail,
34-
public readonly OuterList|Dictionary|InnerList|Item|Parameters|null $expected
37+
public readonly OuterList|Dictionary|Item|null $expected
3538
) {
3639
}
3740

@@ -41,30 +44,31 @@ private function __construct(
4144
public static function fromDecoded(array $data): self
4245
{
4346
$data += ['canonical' => $data['raw'], 'must_fail' => false, 'can_fail' => false, 'expected' => []];
47+
$dataType = DataType::from($data['header_type']);
4448

4549
return new self(
4650
$data['name'],
47-
$data['header_type'],
51+
$dataType,
4852
$data['raw'],
4953
$data['canonical'],
5054
$data['must_fail'],
5155
$data['can_fail'],
52-
self::parseExpected($data['header_type'], $data['expected'])
56+
self::parseExpected($dataType, $data['expected'])
5357
);
5458
}
5559

56-
private static function parseExpected(string $dataTypeValue, array $expected): OuterList|Dictionary|InnerList|Item|Parameters|null
60+
private static function parseExpected(DataType $dataType, array $expected): OuterList|Dictionary|Item|null
5761
{
58-
return match (DataType::tryFrom($dataTypeValue)) {
62+
return match ($dataType) {
5963
DataType::Dictionary => self::parseDictionary($expected),
6064
DataType::List => self::parseList($expected),
6165
DataType::Item => self::parseItem($expected),
62-
default => null,
66+
default => throw new ValueError('The structured field can not be of the type "'.$dataType->value.'".'),
6367
};
6468
}
6569

6670
/**
67-
* @param itemValue $data
71+
* @param ItemValue $data
6872
*/
6973
private static function parseValue(array|string|bool|int|float|null $data): Token|DateTimeImmutable|Bytes|DisplayString|string|bool|int|float|null
7074
{
@@ -83,7 +87,7 @@ private static function parseValue(array|string|bool|int|float|null $data): Toke
8387
}
8488

8589
/**
86-
* @param array<array{0:string, 1:itemValue> $parameters
90+
* @param array<array{0:string, 1:ItemValue> $parameters
8791
*/
8892
private static function parseParameters(array $parameters): Parameters
8993
{
@@ -94,18 +98,16 @@ private static function parseParameters(array $parameters): Parameters
9498
}
9599

96100
/**
97-
* @param array{0:itemValue, 1:array<array{0:string, 1:itemValue}>}|itemValue $value
101+
* @param array{0:ItemValue, 1:array<array{0:string, 1:ItemValue}>}|ItemValue $value
98102
*/
99-
private static function parseItem(mixed $value): ?Item
103+
private static function parseItem(array|string|int $value): ?Item
100104
{
101-
return match (true) {
102-
!is_array($value) => Item::new($value),
103-
[] === $value => null,
104-
default => Item::new([
105-
self::parseValue($value[0]),
106-
self::parseParameters($value[1]),
107-
]),
108-
};
105+
return Item::tryfromPair(match (true) {
106+
!is_array($value) => [$value],
107+
[] === $value => [],
108+
1 === count($value) => [$value],
109+
default => [self::parseValue($value[0]), self::parseParameters($value[1])],
110+
});
109111
}
110112

111113
private static function parseInnerList(array $innerListPair): InnerList

tests/StructuredFieldTestCase.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ public function it_can_pass_http_wg_tests(Record $test): void
2727
$this->expectException(SyntaxError::class);
2828
}
2929

30-
$structuredField = DataType::from($test->type)->parse(implode(',', $test->raw));
30+
$structuredField = $test->type->parse(implode(',', $test->raw));
3131

3232
if (!$test->mustFail) {
3333
self::assertSame(

0 commit comments

Comments
 (0)