Skip to content

Commit

Permalink
All required automated tests are in place. This commit closes #5
Browse files Browse the repository at this point in the history
  • Loading branch information
blancks committed Nov 6, 2024
1 parent 8a35bde commit 91b143a
Show file tree
Hide file tree
Showing 6 changed files with 489 additions and 0 deletions.
7 changes: 7 additions & 0 deletions tests/operations/AddTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@
use blancks\JsonPatch\json\handlers\BasicJsonHandler;
use blancks\JsonPatch\json\handlers\JsonHandlerAwareTrait;
use blancks\JsonPatch\operations\Add;
use blancks\JsonPatch\operations\PatchOperation;
use blancks\JsonPatch\operations\PatchValidationTrait;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;

#[CoversClass(Add::class)]
#[CoversClass(PatchOperation::class)]
#[UsesClass(PatchValidationTrait::class)]
#[UsesClass(CrudTrait::class)]
#[UsesClass(BasicJsonHandler::class)]
Expand All @@ -42,6 +44,11 @@ protected function setUp(): void
$this->Operation->setJsonHandler(new BasicJsonHandler);
}

public function testGetOperation(): void
{
$this->assertSame('add', $this->Operation->getOperation());
}

public function testValidate(): void
{
$this->expectNotToPerformAssertions();
Expand Down
7 changes: 7 additions & 0 deletions tests/operations/CopyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,14 @@
use blancks\JsonPatch\json\handlers\BasicJsonHandler;
use blancks\JsonPatch\json\handlers\JsonHandlerAwareTrait;
use blancks\JsonPatch\operations\Copy;
use blancks\JsonPatch\operations\PatchOperation;
use blancks\JsonPatch\operations\PatchValidationTrait;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;

#[CoversClass(Copy::class)]
#[CoversClass(PatchOperation::class)]
#[UsesClass(PatchValidationTrait::class)]
#[UsesClass(CrudTrait::class)]
#[UsesClass(BasicJsonHandler::class)]
Expand All @@ -46,6 +48,11 @@ protected function setUp(): void
$this->Operation->setJsonHandler(new BasicJsonHandler);
}

public function testGetOperation(): void
{
$this->assertSame('copy', $this->Operation->getOperation());
}

public function testValidateHandlesValidPatchStructure(): void
{
$this->expectNotToPerformAssertions();
Expand Down
113 changes: 113 additions & 0 deletions tests/operations/MoveTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
<?php declare(strict_types=1);

namespace blancks\JsonPatchTest\operations;

use blancks\JsonPatch\exceptions\FastJsonPatchExceptionTrait;
use blancks\JsonPatch\exceptions\InvalidPatchFromException;
use blancks\JsonPatch\exceptions\MalformedPathException;
use blancks\JsonPatch\exceptions\UnknownPathException;
use blancks\JsonPatch\json\accessors\ArrayAccessor;
use blancks\JsonPatch\json\accessors\ArrayAccessorAwareTrait;
use blancks\JsonPatch\json\accessors\ObjectAccessor;
use blancks\JsonPatch\json\accessors\ObjectAccessorAwareTrait;
use blancks\JsonPatch\json\accessors\ValueAccessor;
use blancks\JsonPatch\json\accessors\ValueAccessorAwareTrait;
use blancks\JsonPatch\json\crud\CrudTrait;
use blancks\JsonPatch\json\handlers\BasicJsonHandler;
use blancks\JsonPatch\json\handlers\JsonHandlerAwareTrait;
use blancks\JsonPatch\operations\Move;
use blancks\JsonPatch\operations\PatchOperation;
use blancks\JsonPatch\operations\PatchValidationTrait;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;

#[CoversClass(Move::class)]
#[CoversClass(PatchOperation::class)]
#[UsesClass(PatchValidationTrait::class)]
#[UsesClass(CrudTrait::class)]
#[UsesClass(BasicJsonHandler::class)]
#[UsesClass(JsonHandlerAwareTrait::class)]
#[UsesClass(ArrayAccessor::class)]
#[UsesClass(ArrayAccessorAwareTrait::class)]
#[UsesClass(ObjectAccessor::class)]
#[UsesClass(ObjectAccessorAwareTrait::class)]
#[UsesClass(ValueAccessor::class)]
#[UsesClass(ValueAccessorAwareTrait::class)]
#[UsesClass(FastJsonPatchExceptionTrait::class)]
#[UsesClass(InvalidPatchFromException::class)]
#[UsesClass(MalformedPathException::class)]
#[UsesClass(UnknownPathException::class)]
class MoveTest extends TestCase
{
private Move $Operation;

protected function setUp(): void
{
$this->Operation = new Move();
$this->Operation->setJsonHandler(new BasicJsonHandler);
}

public function testGetOperation(): void
{
$this->assertSame('move', $this->Operation->getOperation());
}

public function testValidateWithValidPatchObject(): void
{
$move = new Move();
$patch = (object) ['op' => 'move', 'path' => '/path/to/resource', 'from' => '/path/from/resource'];
$move->validate($patch);
$this->assertTrue(true);
}

public function testValidateWithPatchObjectMissingFrom(): void
{
$this->expectException(InvalidPatchFromException::class);
/** @var object{op:string, path: string, from: string} $patch */
$patch = (object) ['op' => 'move', 'path' => '/path/to/resource'];
$this->Operation->validate($patch);
}

public function testValidateWithPatchObjectHavingInvalidFrom(): void
{
$this->expectException(MalformedPathException::class);
$patch = (object) ['op' => 'move', 'path' => '/path/to/resource', 'from' => 'invalid/from/path'];
$this->Operation->validate($patch);
}

public function testApplyWithValidPatchObject(): void
{
$document = (object) [
'path' => (object) ['to' => (object) ['resource' => 'value1']],
'path1' => (object) ['from' => (object) ['resource' => 'value2']]
];
$patch = (object) ['op' => 'move', 'path' => '/path/to/resource', 'from' => '/path1/from/resource'];
$this->Operation->apply($document, $patch);
$this->assertEquals('value2', $document->path->to->resource);
}

public function testApplyWithPatchObjectMissingFrom(): void
{
$this->expectException(UnknownPathException::class);
$document = (object) ['path' => ['to' => ['resource' => 'value1']]];
$patch = (object) ['op' => 'move', 'path' => '/path/to/resource', 'from' => '/path1/from/resource'];
$this->Operation->apply($document, $patch);
}

public function testApplyWithPatchObjectHavingNonExistentFrom(): void
{
$this->expectException(UnknownPathException::class);
$document = (object) ['path' => ['to' => ['resource' => 'value1']]];
$patch = (object) ['op' => 'move', 'path' => '/path/to/resource', 'from' => '/invalid/from/path'];
$this->Operation->apply($document, $patch);
}

public function testGetRevertPatch(): void
{
$patch = (object) ['op' => 'move', 'path' => '/path/to/resource', 'from' => '/path/from/resource'];
$revertedPatch = $this->Operation->getRevertPatch($patch);
$expectedRevertedPatch = ['op' => 'move', 'from' => '/path/to/resource', 'path' => '/path/from/resource'];
$this->assertEquals($expectedRevertedPatch, $revertedPatch);
}
}
95 changes: 95 additions & 0 deletions tests/operations/RemoveTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<?php declare(strict_types=1);

namespace blancks\JsonPatchTest\operations;

use blancks\JsonPatch\exceptions\FastJsonPatchExceptionTrait;
use blancks\JsonPatch\exceptions\InvalidPatchFromException;
use blancks\JsonPatch\exceptions\MalformedPathException;
use blancks\JsonPatch\exceptions\UnknownPathException;
use blancks\JsonPatch\json\accessors\ArrayAccessor;
use blancks\JsonPatch\json\accessors\ArrayAccessorAwareTrait;
use blancks\JsonPatch\json\accessors\ObjectAccessor;
use blancks\JsonPatch\json\accessors\ObjectAccessorAwareTrait;
use blancks\JsonPatch\json\accessors\ValueAccessor;
use blancks\JsonPatch\json\accessors\ValueAccessorAwareTrait;
use blancks\JsonPatch\json\crud\CrudTrait;
use blancks\JsonPatch\json\handlers\BasicJsonHandler;
use blancks\JsonPatch\json\handlers\JsonHandlerAwareTrait;
use blancks\JsonPatch\operations\PatchOperation;
use blancks\JsonPatch\operations\PatchValidationTrait;
use blancks\JsonPatch\operations\Remove;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;

#[CoversClass(Remove::class)]
#[CoversClass(PatchOperation::class)]
#[UsesClass(PatchValidationTrait::class)]
#[UsesClass(CrudTrait::class)]
#[UsesClass(BasicJsonHandler::class)]
#[UsesClass(JsonHandlerAwareTrait::class)]
#[UsesClass(ArrayAccessor::class)]
#[UsesClass(ArrayAccessorAwareTrait::class)]
#[UsesClass(ObjectAccessor::class)]
#[UsesClass(ObjectAccessorAwareTrait::class)]
#[UsesClass(ValueAccessor::class)]
#[UsesClass(ValueAccessorAwareTrait::class)]
#[UsesClass(FastJsonPatchExceptionTrait::class)]
#[UsesClass(InvalidPatchFromException::class)]
#[UsesClass(MalformedPathException::class)]
#[UsesClass(UnknownPathException::class)]
class RemoveTest extends TestCase
{
private Remove $Operation;

protected function setUp(): void
{
$this->Operation = new Remove();
$this->Operation->setJsonHandler(new BasicJsonHandler);
}

public function testGetOperation(): void
{
$this->assertSame('remove', $this->Operation->getOperation());
}

public function testValidateMethodWithValidPatch(): void
{
$validPatch = (object) ['op' => 'remove', 'path' => '/test/path'];
$this->Operation->validate($validPatch);
$this->expectNotToPerformAssertions();
}

public function testApply(): void
{
$document = ['fruit' => 'apple', 'color' => 'red'];
$patch = (object) ['op' => 'remove', 'path' => '/color'];
$this->Operation->apply($document, $patch);
$this->assertSame(['fruit' => 'apple'], $document);
}

public function testApplyWithNonExistingKey(): void
{
$this->expectException(UnknownPathException::class);
$document = ['fruit' => 'apple', 'color' => 'red'];
$patch = (object) ['op' => 'remove', 'path' => '/nope'];
$this->Operation->apply($document, $patch);
}

public function testGetRevertPatchWithPreviousValue(): void
{
$document = ['fruit' => 'apple', 'color' => 'red'];
$patch = (object) ['op' => 'remove', 'path' => '/color'];
$this->Operation->apply($document, $patch);
$revertPatch = $this->Operation->getRevertPatch($patch);
$this->assertSame(['op' => 'add', 'path' => '/color', 'value' => 'red'], $revertPatch);
}

public function testGetRevertPatchWithoutPreviousValue(): void
{
$document = ['fruit' => 'apple', 'color' => 'red'];
$patch = (object) ['op' => 'remove', 'path' => '/flavour'];
$this->expectException(UnknownPathException::class);
$this->Operation->apply($document, $patch);
}
}
121 changes: 121 additions & 0 deletions tests/operations/ReplaceTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php declare(strict_types=1);

namespace blancks\JsonPatchTest\operations;

use blancks\JsonPatch\exceptions\FastJsonPatchExceptionTrait;
use blancks\JsonPatch\exceptions\InvalidPatchFromException;
use blancks\JsonPatch\exceptions\InvalidPatchValueException;
use blancks\JsonPatch\exceptions\MalformedPathException;
use blancks\JsonPatch\exceptions\UnknownPathException;
use blancks\JsonPatch\json\accessors\ArrayAccessor;
use blancks\JsonPatch\json\accessors\ArrayAccessorAwareTrait;
use blancks\JsonPatch\json\accessors\ObjectAccessor;
use blancks\JsonPatch\json\accessors\ObjectAccessorAwareTrait;
use blancks\JsonPatch\json\accessors\ValueAccessor;
use blancks\JsonPatch\json\accessors\ValueAccessorAwareTrait;
use blancks\JsonPatch\json\crud\CrudTrait;
use blancks\JsonPatch\json\handlers\BasicJsonHandler;
use blancks\JsonPatch\json\handlers\JsonHandlerAwareTrait;
use blancks\JsonPatch\operations\PatchOperation;
use blancks\JsonPatch\operations\PatchValidationTrait;
use blancks\JsonPatch\operations\Replace;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\UsesClass;
use PHPUnit\Framework\TestCase;

#[CoversClass(Replace::class)]
#[CoversClass(PatchOperation::class)]
#[UsesClass(PatchValidationTrait::class)]
#[UsesClass(CrudTrait::class)]
#[UsesClass(BasicJsonHandler::class)]
#[UsesClass(JsonHandlerAwareTrait::class)]
#[UsesClass(ArrayAccessor::class)]
#[UsesClass(ArrayAccessorAwareTrait::class)]
#[UsesClass(ObjectAccessor::class)]
#[UsesClass(ObjectAccessorAwareTrait::class)]
#[UsesClass(ValueAccessor::class)]
#[UsesClass(ValueAccessorAwareTrait::class)]
#[UsesClass(FastJsonPatchExceptionTrait::class)]
#[UsesClass(InvalidPatchFromException::class)]
#[UsesClass(MalformedPathException::class)]
#[UsesClass(UnknownPathException::class)]
#[UsesClass(InvalidPatchValueException::class)]
class ReplaceTest extends TestCase
{
private Replace $Operation;

protected function setUp(): void
{
$this->Operation = new Replace();
$this->Operation->setJsonHandler(new BasicJsonHandler);
}

public function testGetOperation(): void
{
$this->assertSame('replace', $this->Operation->getOperation());
}

public function testValidPatch(): void
{
$this->expectNotToPerformAssertions();
$patch = (object) ['op' => 'replace', 'path' => '/valid/path', 'value' => 'valid value'];
$this->Operation->validate($patch);
}

public function testInvalidPatchThrowsException(): void
{
$this->expectException(InvalidPatchValueException::class);

/** @var object{op:string, path: string, value: mixed} $patch */
$patch = (object) [
'op' => 'replace',
'path' => '/valid/path',
// value is missing
];
$this->Operation->validate($patch);
}

public function testApplyToAssociativeDocumentWithValidReplacePatch(): void
{
$document = ['simpleKey' => 'simpleValue'];
$patch = (object) ['op' => 'replace', 'path' => '/simpleKey', 'value' => 'changedValue'];
$this->Operation->apply($document, $patch);
$this->assertSame('changedValue', $document['simpleKey']);
}

public function testApplyToObjectDocumentWithValidReplacePatch(): void
{
$document = (object) ['simpleKey' => 'simpleValue'];
$patch = (object) ['op' => 'replace', 'path' => '/simpleKey', 'value' => 'changedValue'];
$this->Operation->apply($document, $patch);
$this->assertSame('changedValue', $document->simpleKey);
}

public function testApplyWithInvalidPathThrowsException(): void
{
$this->expectException(UnknownPathException::class);
$document = [
'simpleKey' => 'simpleValue',
];
$patch = (object) ['op' => 'replace', 'path' => '/unknown/path', 'value' => 'valueToReplace'];
$this->Operation->apply($document, $patch);
}

public function testGetRevertPatch(): void
{
$document = (object) ['simpleKey' => 'simpleValue'];
$patch = (object) ['op' => 'replace', 'path' => '/simpleKey', 'value' => 'changedValue'];
$this->Operation->apply($document, $patch);
$revertedPatch = $this->Operation->getRevertPatch($patch);
$this->assertSame(['op' => 'replace', 'path' => '/simpleKey', 'value' => 'simpleValue'], $revertedPatch);
}

public function testGetRevertPatchWithNullPreviousValue(): void
{
$document = (object) ['simpleKey' => null];
$patch = (object) ['op' => 'replace', 'path' => '/simpleKey', 'value' => 'changedValue'];
$this->Operation->apply($document, $patch);
$revertedPatch = $this->Operation->getRevertPatch($patch);
$this->assertSame(['op' => 'replace', 'path' => '/simpleKey', 'value' => null], $revertedPatch);
}
}
Loading

0 comments on commit 91b143a

Please sign in to comment.