Schneespur — Open-source winter service documentation software (PWA + Admin). GPS tracking via OwnTracks, weather data, photo evidence, and legally compliant service records for winter maintenance operators. License: AGPL-3.0-or-later
189 lines
5.6 KiB
PHP
189 lines
5.6 KiB
PHP
<?php
|
|
|
|
/**
|
|
* League.Uri (https://uri.thephpleague.com)
|
|
*
|
|
* (c) Ignace Nyamagana Butera <nyamsprod@gmail.com>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace League\Uri\UriTemplate;
|
|
|
|
use JsonException;
|
|
use League\Uri\Exceptions\SyntaxError;
|
|
use PHPUnit\Framework\Attributes\CoversClass;
|
|
use PHPUnit\Framework\Attributes\DataProvider;
|
|
use PHPUnit\Framework\Attributes\Test;
|
|
use PHPUnit\Framework\TestCase;
|
|
use RuntimeException;
|
|
use Throwable;
|
|
|
|
use const JSON_THROW_ON_ERROR;
|
|
|
|
#[CoversClass(Template::class)]
|
|
final class TemplateTest extends TestCase
|
|
{
|
|
private static string $rootPath = __DIR__.'/../../vendor/uri-templates/uritemplate-test';
|
|
|
|
/** @var array<string> */
|
|
private static array $testFilenames = [
|
|
'spec-examples.json',
|
|
'negative-tests.json',
|
|
'extended-tests.json',
|
|
];
|
|
|
|
#[DataProvider('uriTemplateSpecificationDataProvider')]
|
|
#[Test]
|
|
public function testItCompliesWithUriTemplatesExpansionTests(
|
|
array $variables,
|
|
string $input,
|
|
string|array|false $expected
|
|
): void {
|
|
if (false === $expected) {
|
|
$this->expectException(Throwable::class);
|
|
}
|
|
|
|
$result = Template::new($input)->expand(new VariableBag($variables));
|
|
|
|
if (is_array($expected)) {
|
|
self::assertContains($result, $expected);
|
|
} else {
|
|
self::assertSame($expected, $result);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @throws JsonException
|
|
* @throws RuntimeException
|
|
* @return iterable<string, array{
|
|
* variables:array{string, string|int},
|
|
* input:string,
|
|
* expected:string|array<string>|false
|
|
* }>
|
|
*/
|
|
public static function uriTemplateSpecificationDataProvider(): iterable
|
|
{
|
|
foreach (static::$testFilenames as $path) {
|
|
$path = static::$rootPath.'/'.ltrim($path, '/');
|
|
if (false === $content = file_get_contents($path)) {
|
|
throw new RuntimeException("unable to connect to the path `$path`.");
|
|
}
|
|
|
|
/** @var array $records */
|
|
$records = json_decode($content, true, 512, JSON_THROW_ON_ERROR);
|
|
foreach ($records as $title => $testSuite) {
|
|
$level = $testSuite['level'] ?? null;
|
|
$variables = $testSuite['variables'];
|
|
foreach ($testSuite['testcases'] as $offset => [$input, $expected]) {
|
|
yield $title.' - '.$level.' # '.($offset + 1) => [
|
|
'variables' => $variables,
|
|
'input' => $input,
|
|
'expected' => $expected,
|
|
];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[DataProvider('providesValidNotation')]
|
|
public function testItCanBeInstantiatedWithAValidNotation(string $notation): void
|
|
{
|
|
self::assertSame($notation, Template::new($notation)->value);
|
|
self::assertSame($notation, (string) Template::new($notation));
|
|
}
|
|
|
|
public static function providesValidNotation(): iterable
|
|
{
|
|
return [
|
|
'complex template' => ['http://example.com{+path}{/segments}{?query,more*,foo[]*}'],
|
|
'template without expression' => ['foobar'],
|
|
|
|
];
|
|
}
|
|
|
|
#[DataProvider('providesInvalidNotation')]
|
|
public function testItFailsToInstantiatedWithAnInvalidNotation(string $notation): void
|
|
{
|
|
self::expectException(SyntaxError::class);
|
|
|
|
Template::new($notation);
|
|
}
|
|
|
|
public static function providesInvalidNotation(): iterable
|
|
{
|
|
return [
|
|
['fooba{r'],
|
|
['fooba}r'],
|
|
['fooba}{r'],
|
|
['{foo{bar'],
|
|
['{foo}}bar'],
|
|
];
|
|
}
|
|
|
|
#[DataProvider('expectedVariableNames')]
|
|
public function testGetVariableNames(string $template, array $expected): void
|
|
{
|
|
self::assertSame($expected, Template::new($template)->variableNames);
|
|
}
|
|
|
|
public static function expectedVariableNames(): iterable
|
|
{
|
|
return [
|
|
[
|
|
'template' => '',
|
|
'expected' => [],
|
|
],
|
|
[
|
|
'template' => '{foo}{bar}{420}',
|
|
'expected' => ['foo', 'bar', '420'],
|
|
],
|
|
[
|
|
'template' => '{foo}{foo:2}{+foo}',
|
|
'expected' => ['foo'],
|
|
],
|
|
[
|
|
'template' => '{bar}{foo}',
|
|
'expected' => ['bar', 'foo'],
|
|
],
|
|
];
|
|
}
|
|
|
|
#[DataProvider('providesExpansion')]
|
|
public function testItCanExpandVariables(string $notation, array $variables, string $expected): void
|
|
{
|
|
self::assertSame($expected, Template::new($notation)->expand($variables));
|
|
}
|
|
|
|
public static function providesExpansion(): iterable
|
|
{
|
|
return [
|
|
'with variables' => [
|
|
'notation' => 'foobar{var}',
|
|
'variables' => ['var' => 'yolo'],
|
|
'expected' => 'foobaryolo',
|
|
],
|
|
'with no variables' => [
|
|
'notation' => 'foobar',
|
|
'variables' => [],
|
|
'expected' => 'foobar',
|
|
],
|
|
];
|
|
}
|
|
|
|
public function testExpandOrFailIfAtLeastOneVariableIsMissing(): void
|
|
{
|
|
$this->expectException(TemplateCanNotBeExpanded::class);
|
|
|
|
Template::new('{var}{baz}')->expandOrFail(['var' => 'bar']);
|
|
}
|
|
|
|
#[Test]
|
|
public function it_can_expand_with_expand_or_fail_when_all_variables_are_present(): void
|
|
{
|
|
self::assertSame('barfoo', Template::new('{var}{baz}')->expandOrFail(['var' => 'bar', 'baz' => 'foo']));
|
|
}
|
|
}
|