Skip to content

Commit

Permalink
[BREAKING] ensure itemAtPath accesses unique value only (#8)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim MacDonald committed Aug 6, 2021
1 parent 41a74fd commit fd7c457
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 7 deletions.
13 changes: 10 additions & 3 deletions src/PathQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,21 @@

use BigPictureMedical\OpenEhr\Rm\Common\Archetyped\Pathable;
use Illuminate\Support\Collection;
use RuntimeException;

class PathQuery
{
public function __construct(protected string $query) {}

public function find(Pathable $root): mixed
{
return $this->findList($root)[0] ?? null;
$items = $this->findList($root);

if (count($items) > 1) {
throw new RuntimeException('Found multiple items at path. Found '.count($items).', expected 1.');
}

return $items[0] ?? null;
}

public function findList(Pathable $root): array
Expand Down Expand Up @@ -50,11 +57,11 @@ private function segments(): Collection
$attributePattern = '(?<attribute_name>\w+)';
$predicatePattern = '(?<predicate>\[(?<expression>[\w.-]+)\])?';
if (preg_match('/^' . $attributePattern . $predicatePattern . '$/', $segment, $matches) !== 1) {
throw new \Exception("Unable to parse path segment [$segment]");
throw new RuntimeException("Unable to parse path segment [$segment]");
}

if (! array_key_exists('attribute_name', $matches)) {
throw new \Exception("Unable to find attribute_name in path segment [$segment]");
throw new RuntimeException("Unable to find attribute_name in path segment [$segment]");
}

return $matches;
Expand Down
21 changes: 19 additions & 2 deletions tests/PathQueryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,29 @@
use BigPictureMedical\OpenEhr\Rm\DataTypes\Text\DvCodedText;
use BigPictureMedical\OpenEhr\Rm\DataTypes\Text\DvText;
use PHPUnit\Framework\TestCase;
use RuntimeException;

class PathQueryTest extends TestCase
{
public function test_it_finds_a_single_item()
{
$composition = $this->makeComposition();

$result = (new PathQuery('content[test-EVALUATION.test.v0]/data/items[at0002]/items[at0003]/value/value'))
$result = (new PathQuery('content[test-EVALUATION.test.v0]/data/items[at0002]/items[at0004]/value/value'))
->find($composition);

$this->assertSame('Test value 1', $result);
$this->assertSame('Test unique value', $result);
}

public function test_it_throws_when_find_has_multiple_results()
{
$composition = $this->makeComposition();

$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Found multiple items at path. Found 4, expected 1.');

(new PathQuery('content[test-EVALUATION.test.v0]/data/items[at0002]/items[at0003]/value/value'))
->find($composition);
}

public function test_it_handles_missing_paths_when_finding_a_single_item()
Expand Down Expand Up @@ -141,6 +153,11 @@ private function makeComposition(): Composition
name: new DvText(value: 'Test element'),
value: new DvText(value: 'Test value 2')
),
new Element(
archetype_node_id: 'at0004',
name: new DvText(value: 'Test element'),
value: new DvText(value: 'Test unique value')
),
]
),
new Cluster(
Expand Down
20 changes: 18 additions & 2 deletions tests/PathableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,27 @@
use BigPictureMedical\OpenEhr\Rm\DataTypes\Text\DvCodedText;
use BigPictureMedical\OpenEhr\Rm\DataTypes\Text\DvText;
use PHPUnit\Framework\TestCase;
use RuntimeException;

class PathableTest extends TestCase
{
public function test_it_finds_an_item_at_path()
{
$composition = $this->makeComposition();

$result = $composition->itemAtPath('content[test-EVALUATION.test.v0]/data/items[at0002]/items[at0003]/value/value');
$result = $composition->itemAtPath('content[test-EVALUATION.test.v0]/data/items[at0002]/items[at0004]/value/value');

$this->assertSame('Test value 1', $result);
$this->assertSame('Test unique value', $result);
}

public function test_it_throws_when_find_has_multiple_results()
{
$composition = $this->makeComposition();

$this->expectException(RuntimeException::class);
$this->expectExceptionMessage('Found multiple items at path. Found 4, expected 1.');

$composition->itemAtPath('content[test-EVALUATION.test.v0]/data/items[at0002]/items[at0003]/value/value');
}

public function test_it_finds_items_at_path()
Expand Down Expand Up @@ -89,6 +100,11 @@ private function makeComposition(): Composition
name: new DvText(value: 'Test element'),
value: new DvText(value: 'Test value 2')
),
new Element(
archetype_node_id: 'at0004',
name: new DvText(value: 'Test element'),
value: new DvText(value: 'Test unique value')
),
]
),
new Cluster(
Expand Down

0 comments on commit fd7c457

Please sign in to comment.