Skip to content

Commit 9ae6248

Browse files
committed
Issue #6: locator builder supports export to string
1 parent fb61809 commit 9ae6248

File tree

4 files changed

+78
-0
lines changed

4 files changed

+78
-0
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [Unreleased]
8+
### Added
9+
- Issue #6: locator builder supports export to string.
10+
711
## [0.6.4] - 2019-11-20
812
### Added
913
- Issue #5: `ResultInterface::get()` method added.

src/Locator/LocatorBuilder.php

+26
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@
33

44
namespace Remorhaz\JSON\Pointer\Locator;
55

6+
use function array_map;
7+
use function implode;
8+
use function str_replace;
9+
610
final class LocatorBuilder implements LocatorBuilderInterface
711
{
812

@@ -42,4 +46,26 @@ public function getLocator(): LocatorInterface
4246

4347
return $this->locator;
4448
}
49+
50+
public function export(): string
51+
{
52+
$references = $this
53+
->getLocator()
54+
->references();
55+
56+
if (empty($references)) {
57+
return '';
58+
}
59+
60+
return '/' . implode('/', array_map([$this, 'escapeReference'], $references));
61+
}
62+
63+
private function escapeReference(ListedReferenceInterface $reference): string
64+
{
65+
$text = $reference
66+
->getReference()
67+
->getPropertyName();
68+
69+
return str_replace(['~', '/'], ['~0', '~1'], $text);
70+
}
4571
}

src/Locator/LocatorBuilderInterface.php

+2
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,6 @@ interface LocatorBuilderInterface
99
public function addReference(string $text): void;
1010

1111
public function getLocator(): LocatorInterface;
12+
13+
public function export(): string;
1214
}

tests/Locator/LocatorBuilderTest.php

+46
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
use PHPUnit\Framework\TestCase;
77
use Remorhaz\JSON\Pointer\Locator\ListedReferenceInterface;
8+
use Remorhaz\JSON\Pointer\Locator\ReferenceFactory;
89
use Remorhaz\JSON\Pointer\Locator\ReferenceFactoryInterface;
910
use Remorhaz\JSON\Pointer\Locator\ReferenceInterface;
1011
use Remorhaz\JSON\Pointer\Locator\Exception\LocatorAlreadyBuiltException;
@@ -44,6 +45,14 @@ public function testAddReference_GetLocatorCalled_ThrowsException(): void
4445
$builder->addReference('a');
4546
}
4647

48+
public function testAddReference_ExportCalled_ThrowsException(): void
49+
{
50+
$builder = new LocatorBuilder($this->createMock(ReferenceFactoryInterface::class));
51+
$builder->export();
52+
$this->expectException(LocatorAlreadyBuiltException::class);
53+
$builder->addReference('a');
54+
}
55+
4756
public function testAddReference_ConstructedWithReferenceFactory_PassesTextToSameInstance(): void
4857
{
4958
$referenceFactory = $this->createMock(ReferenceFactoryInterface::class);
@@ -80,4 +89,41 @@ function (ListedReferenceInterface $listedReference): ReferenceInterface {
8089
);
8190
self::assertSame([$firstReference, $secondReference], $actualValue);
8291
}
92+
93+
public function testExport_NoReferencesAdded_ReturnsEmptyPointer(): void
94+
{
95+
$referenceFactory = $this->createMock(ReferenceFactoryInterface::class);
96+
$builder = new LocatorBuilder($referenceFactory);
97+
self::assertSame('', $builder->export());
98+
}
99+
100+
/**
101+
* @param string $text
102+
* @param string $expectedValue
103+
* @dataProvider providerExportSingleReference
104+
*/
105+
public function testExport_SingleReferenceAdded_ReturnsMatchingPointer(string $text, string $expectedValue): void
106+
{
107+
$builder = new LocatorBuilder(new ReferenceFactory);
108+
$builder->addReference($text);
109+
self::assertSame($expectedValue, $builder->export());
110+
}
111+
public function providerExportSingleReference(): array
112+
{
113+
return [
114+
'ASCII string' => ['a', '/a'],
115+
'Tilde' => ['~', '/~0'],
116+
'Slash' => ['/', '/~1'],
117+
'Tilde after slash' => ['/~', '/~1~0'],
118+
'Slash after tilde' => ['~/', '/~0~1'],
119+
];
120+
}
121+
122+
public function testExport_TwoReferencesAdded_ReturnsMatchingPointer(): void
123+
{
124+
$builder = new LocatorBuilder(new ReferenceFactory);
125+
$builder->addReference('a');
126+
$builder->addReference('b');
127+
self::assertSame('/a/b', $builder->export());
128+
}
83129
}

0 commit comments

Comments
 (0)