Skip to content

Commit 16734bb

Browse files
committed
Query test added
1 parent 8091bf1 commit 16734bb

File tree

2 files changed

+199
-4
lines changed

2 files changed

+199
-4
lines changed

src/Query/LazyQuery.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace Remorhaz\JSON\Patch\Query;
55

6+
use Iterator;
67
use Remorhaz\JSON\Data\Export\ValueDecoderInterface;
78
use Remorhaz\JSON\Data\Export\ValueEncoderInterface;
89
use Remorhaz\JSON\Data\Value\ArrayValueInterface;
@@ -55,10 +56,7 @@ private function loadQuery(): QueryInterface
5556
{
5657
$operations = [];
5758
try {
58-
if (!$this->patch instanceof ArrayValueInterface) {
59-
throw new Exception\InvalidPatchException($this->patch);
60-
}
61-
foreach ($this->patch->createChildIterator() as $index => $operationData) {
59+
foreach ($this->createOperationDataIterator($this->patch) as $index => $operationData) {
6260
$operations[] = $this
6361
->operationFactory
6462
->fromJson($operationData, $index);
@@ -69,4 +67,13 @@ private function loadQuery(): QueryInterface
6967

7068
return new Query($this->encoder, $this->decoder, ...$operations);
7169
}
70+
71+
private function createOperationDataIterator(NodeValueInterface $patch): Iterator
72+
{
73+
if ($patch instanceof ArrayValueInterface) {
74+
return $patch->createChildIterator();
75+
}
76+
77+
throw new Exception\InvalidPatchException($patch);
78+
}
7279
}

tests/Query/QueryTest.php

Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
<?php
2+
declare(strict_types=1);
3+
4+
namespace Remorhaz\JSON\Patch\Test\Query;
5+
6+
use PHPUnit\Framework\TestCase;
7+
use Remorhaz\JSON\Data\Export\ValueDecoderInterface;
8+
use Remorhaz\JSON\Data\Export\ValueEncoderInterface;
9+
use Remorhaz\JSON\Data\Value\NodeValueInterface;
10+
use Remorhaz\JSON\Patch\Exception\ExceptionInterface as PatchExceptionInterface;
11+
use Remorhaz\JSON\Patch\Operation\OperationInterface;
12+
use Remorhaz\JSON\Patch\Query\Query;
13+
use Remorhaz\JSON\Pointer\Processor\ProcessorInterface as PointerProcessorInterface;
14+
15+
/**
16+
* @covers \Remorhaz\JSON\Patch\Query\Query
17+
*/
18+
class QueryTest extends TestCase
19+
{
20+
21+
/**
22+
* @throws PatchExceptionInterface
23+
*/
24+
public function testInvoke_ConstructedWithEncoder_UsesSameInstanceOnResultEncode(): void
25+
{
26+
$encoder = $this->createMock(ValueEncoderInterface::class);
27+
$query = new Query(
28+
$encoder,
29+
$this->createMock(ValueDecoderInterface::class)
30+
);
31+
$result = $query(
32+
$this->createMock(NodeValueInterface::class),
33+
$this->createMock(PointerProcessorInterface::class)
34+
);
35+
$encoder
36+
->expects(self::once())
37+
->method('exportValue');
38+
$result->encode();
39+
}
40+
41+
/**
42+
* @throws PatchExceptionInterface
43+
*/
44+
public function testInvoke_ConstructedWithDecoder_UsesSameInstanceOnResultDecode(): void
45+
{
46+
$decoder = $this->createMock(ValueDecoderInterface::class);
47+
$query = new Query(
48+
$this->createMock(ValueEncoderInterface::class),
49+
$decoder
50+
);
51+
$result = $query(
52+
$this->createMock(NodeValueInterface::class),
53+
$this->createMock(PointerProcessorInterface::class)
54+
);
55+
$decoder
56+
->expects(self::once())
57+
->method('exportValue');
58+
$result->decode();
59+
}
60+
61+
/**
62+
* @throws PatchExceptionInterface
63+
*/
64+
public function testInvoke_ConstructedWithoutOperations_ReturnsInputInResult(): void
65+
{
66+
$query = new Query(
67+
$this->createMock(ValueEncoderInterface::class),
68+
$this->createMock(ValueDecoderInterface::class)
69+
);
70+
$input = $this->createMock(NodeValueInterface::class);
71+
$result = $query(
72+
$input,
73+
$this->createMock(PointerProcessorInterface::class)
74+
);
75+
self::assertSame($input, $result->get());
76+
}
77+
78+
/**
79+
* @throws PatchExceptionInterface
80+
*/
81+
public function testInvoke_ConstructedWithSingleOperation_PassesInputToOperation(): void
82+
{
83+
$operation = $this->createMock(OperationInterface::class);
84+
$query = new Query(
85+
$this->createMock(ValueEncoderInterface::class),
86+
$this->createMock(ValueDecoderInterface::class),
87+
$operation
88+
);
89+
$input = $this->createMock(NodeValueInterface::class);
90+
$pointerProcessor = $this->createMock(PointerProcessorInterface::class);
91+
$operation
92+
->expects(self::once())
93+
->method('apply')
94+
->with(self::identicalTo($input), self::identicalTo($pointerProcessor));
95+
$query($input, $pointerProcessor);
96+
}
97+
98+
/**
99+
* @throws PatchExceptionInterface
100+
*/
101+
public function testInvoke_ConstructedWithTwoOperations_PassesInputToFirstOperation(): void
102+
{
103+
$operation = $this->createMock(OperationInterface::class);
104+
$query = new Query(
105+
$this->createMock(ValueEncoderInterface::class),
106+
$this->createMock(ValueDecoderInterface::class),
107+
$operation,
108+
$this->createMock(OperationInterface::class)
109+
);
110+
$input = $this->createMock(NodeValueInterface::class);
111+
$pointerProcessor = $this->createMock(PointerProcessorInterface::class);
112+
$operation
113+
->expects(self::once())
114+
->method('apply')
115+
->with(self::identicalTo($input), self::identicalTo($pointerProcessor));
116+
$query($input, $pointerProcessor);
117+
}
118+
119+
/**
120+
* @throws PatchExceptionInterface
121+
*/
122+
public function testInvoke_ConstructedWithTwoOperations_PassesFirstOperationResultToSecondOperation(): void
123+
{
124+
$firstOperation = $this->createMock(OperationInterface::class);
125+
$secondOperation = $this->createMock(OperationInterface::class);
126+
$query = new Query(
127+
$this->createMock(ValueEncoderInterface::class),
128+
$this->createMock(ValueDecoderInterface::class),
129+
$firstOperation,
130+
$secondOperation
131+
);
132+
$firstOperationResult = $this->createMock(NodeValueInterface::class);
133+
$pointerProcessor = $this->createMock(PointerProcessorInterface::class);
134+
$firstOperation
135+
->method('apply')
136+
->willReturn($firstOperationResult);
137+
$secondOperation
138+
->expects(self::once())
139+
->method('apply')
140+
->with(self::identicalTo($firstOperationResult), self::identicalTo($pointerProcessor));
141+
$query($firstOperationResult, $pointerProcessor);
142+
}
143+
144+
/**
145+
* @throws PatchExceptionInterface
146+
*/
147+
public function testInvoke_ConstructedWithSingleOperation_ReturnsOperationApplicationInResult(): void
148+
{
149+
$operation = $this->createMock(OperationInterface::class);
150+
$query = new Query(
151+
$this->createMock(ValueEncoderInterface::class),
152+
$this->createMock(ValueDecoderInterface::class),
153+
$operation
154+
);
155+
$output = $this->createMock(NodeValueInterface::class);
156+
$operation
157+
->method('apply')
158+
->willReturn($output);
159+
$result = $query(
160+
$this->createMock(NodeValueInterface::class),
161+
$this->createMock(PointerProcessorInterface::class)
162+
);
163+
self::assertSame($output, $result->get());
164+
}
165+
166+
/**
167+
* @throws PatchExceptionInterface
168+
*/
169+
public function testInvoke_ConstructedWithTwoOperations_ReturnsLastOperationApplicationInResult(): void
170+
{
171+
$operation = $this->createMock(OperationInterface::class);
172+
$query = new Query(
173+
$this->createMock(ValueEncoderInterface::class),
174+
$this->createMock(ValueDecoderInterface::class),
175+
$this->createMock(OperationInterface::class),
176+
$operation
177+
);
178+
$output = $this->createMock(NodeValueInterface::class);
179+
$operation
180+
->method('apply')
181+
->willReturn($output);
182+
$result = $query(
183+
$this->createMock(NodeValueInterface::class),
184+
$this->createMock(PointerProcessorInterface::class)
185+
);
186+
self::assertSame($output, $result->get());
187+
}
188+
}

0 commit comments

Comments
 (0)