Test lazy pointers and lazy loading

This commit is contained in:
Andrea Marco Sartori 2023-03-20 19:33:16 +10:00
parent b6b965d7fc
commit 863a3eb77c
3 changed files with 137 additions and 3 deletions

View File

@ -8,6 +8,7 @@ use Cerbero\JsonParser\Sources\Psr7Request;
use DirectoryIterator;
use Generator;
use Mockery;
use Pest\Expectation;
/**
* The dataset provider.
@ -176,6 +177,107 @@ final class Dataset
}
}
/**
* Retrieve the dataset to test single lazy pointers
*
* @return Generator
*/
public static function forSingleLazyPointers(): Generator
{
$json = fixture('json/complex_object.json');
$sequenceByPointer = [
'' => [
fn ($value, $key) => $key->toBe('id')->and($value->value)->toBe('0001'),
fn ($value, $key) => $key->toBe('type')->and($value->value)->toBe('donut'),
fn ($value, $key) => $key->toBe('name')->and($value->value)->toBe('Cake'),
fn ($value, $key) => $key->toBe('ppu')->and($value->value)->toBe(0.55),
fn ($value, $key) => $key->toBe('batters')->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe('topping')->and($value->value)->toBeInstanceOf(Parser::class),
],
'/batters/batter/-' => [
fn ($value, $key) => $key->toBe(0)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(1)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(2)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(3)->and($value->value)->toBeInstanceOf(Parser::class),
],
'/topping/-' => [
fn ($value, $key) => $key->toBe(0)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(1)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(2)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(3)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(4)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(5)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(6)->and($value->value)->toBeInstanceOf(Parser::class),
],
];
foreach ($sequenceByPointer as $pointer => $sequence) {
yield [$json, $pointer, $sequence];
}
}
/**
* Retrieve the dataset to test multiple lazy pointers
*
* @return Generator
*/
public static function forMultipleLazyPointers(): Generator
{
$json = fixture('json/complex_object.json');
$sequenceByPointer = [
'/topping,/batters' => [
fn ($value, $key) => $key->toBe('batters')->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe('topping')->and($value->value)->toBeInstanceOf(Parser::class),
],
'/topping/-,/batters/batter' => [
fn ($value, $key) => $key->toBe('batter')->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(0)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(1)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(2)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(3)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(4)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(5)->and($value->value)->toBeInstanceOf(Parser::class),
fn ($value, $key) => $key->toBe(6)->and($value->value)->toBeInstanceOf(Parser::class),
],
];
foreach ($sequenceByPointer as $pointers => $sequence) {
yield [$json, explode(',', $pointers), $sequence];
}
}
/**
* Retrieve the dataset to test recursive lazy loading
*
* @return Generator
*/
public static function forRecursiveLazyLoading(): Generator
{
$json = fixture('json/complex_object.json');
$expectedByKeys = [
'batters,batter' => [
['id' => '1001', 'type' => 'Regular'],
['id' => '1002', 'type' => 'Chocolate'],
['id' => '1003', 'type' => 'Blueberry'],
['id' => '1004', 'type' => 'Devil\'s Food'],
],
'topping' => [
['id' => '5001', 'type' => 'None'],
['id' => '5002', 'type' => 'Glazed'],
['id' => '5005', 'type' => 'Sugar'],
['id' => '5007', 'type' => 'Powdered Sugar'],
['id' => '5006', 'type' => 'Chocolate with Sprinkles'],
['id' => '5003', 'type' => 'Chocolate'],
['id' => '5004', 'type' => 'Maple'],
],
];
foreach ($expectedByKeys as $keys => $expected) {
$keys = explode(',', $keys);
yield [$json, '/' . $keys[0], $keys, $expected];
}
}
/**
* Retrieve the dataset to test syntax errors
*

View File

@ -11,11 +11,11 @@ it('throws an exception when providing an invalid JSON pointer', function (strin
->toThrow(InvalidPointerException::class, "The string [$pointer] is not a valid JSON pointer");
})->with(Dataset::forInvalidPointers());
it('supports single JSON pointers', function (string $json, string $pointer, array $parsed) {
it('loads JSON from a single JSON pointer', function (string $json, string $pointer, array $parsed) {
expect(JsonParser::parse($json)->pointer($pointer))->toPointTo($parsed);
})->with(Dataset::forSinglePointers());
it('supports multiple JSON pointers', function (string $json, array $pointers, array $parsed) {
it('loads JSON from multiple JSON pointers', function (string $json, array $pointers, array $parsed) {
expect(JsonParser::parse($json)->pointers($pointers))->toPointTo($parsed);
})->with(Dataset::forMultiplePointers());
@ -24,6 +24,18 @@ it('can intersect pointers with wildcards', function (string $json, array $point
})->with(Dataset::forIntersectingPointersWithWildcards());
it('throws an exception when two pointers intersect', function (string $json, array $pointers, string $message) {
expect(fn () => JsonParser::parse($json)->pointers($pointers)->traverse())
expect(fn () => JsonParser::parse($json)->pointers($pointers))
->toThrow(IntersectingPointersException::class, $message);
})->with(Dataset::forIntersectingPointers());
it('lazy loads JSON from a single lazy JSON pointer', function (string $json, string $pointer, array $sequence) {
expect(JsonParser::parse($json)->lazyPointer($pointer))->sequence(...$sequence);
})->with(Dataset::forSingleLazyPointers());
it('lazy loads JSON from multiple lazy JSON pointers', function (string $json, array $pointers, array $sequence) {
expect(JsonParser::parse($json)->lazyPointers($pointers))->sequence(...$sequence);
})->with(Dataset::forMultipleLazyPointers());
it('lazy loads JSON recursively', function (string $json, string $pointer, array $keys, array $expected) {
expect(JsonParser::parse($json)->lazyPointer($pointer))->toLazyLoadRecursively($keys, $expected);
})->with(Dataset::forRecursiveLazyLoading());

View File

@ -1,5 +1,7 @@
<?php
use Cerbero\JsonParser\Parser;
if (!function_exists('fixture')) {
/**
* Retrieve the absolute path of the given fixture
@ -54,3 +56,21 @@ expect()->extend('toPointTo', function (array $expected) {
return expect($actual)->toBe($expected);
});
/**
* Expect that values defined by lazy JSON pointers are parsed correctly
*
* @param array $expected
* @return Expectation
*/
expect()->extend('toLazyLoadRecursively', function (array $keys, array $expected) {
foreach ($this->value as $key => $value) {
expect($value)->toBeInstanceOf(Parser::class);
if (is_null($expectedKey = array_shift($keys))) {
expect($key)->toBeInt()->and($value)->toParseTo($expected[$key]);
} else {
expect($key)->toBe($expectedKey)->and($value)->toLazyLoadRecursively($keys, $expected);
}
}
});