Add pjson support
This commit is contained in:
		
							parent
							
								
									50854275a8
								
							
						
					
					
						commit
						478684621c
					
				@ -23,7 +23,8 @@
 | 
			
		||||
    "phpoption/phpoption": "^1.9"
 | 
			
		||||
  },
 | 
			
		||||
  "require-dev": {
 | 
			
		||||
    "phpunit/phpunit": "^11"
 | 
			
		||||
    "phpunit/phpunit": "^11",
 | 
			
		||||
    "square/pjson": "^0.5.0"
 | 
			
		||||
  },
 | 
			
		||||
  "autoload": {
 | 
			
		||||
    "psr-4": {
 | 
			
		||||
@ -34,6 +35,7 @@
 | 
			
		||||
  },
 | 
			
		||||
  "autoload-dev": {
 | 
			
		||||
    "psr-4": {
 | 
			
		||||
      "Test\\": "./tests",
 | 
			
		||||
      "Test\\Unit\\": "./tests/unit",
 | 
			
		||||
      "Test\\Integration\\": "./tests/integration",
 | 
			
		||||
      "Test\\Integration\\PostgreSQL\\": "./tests/integration/postgresql",
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										62
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										62
									
								
								composer.lock
									
									
									
										generated
									
									
									
								
							@ -4,7 +4,7 @@
 | 
			
		||||
        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
 | 
			
		||||
        "This file is @generated automatically"
 | 
			
		||||
    ],
 | 
			
		||||
    "content-hash": "71593fca8aa32b0cd963eb52bad1a34e",
 | 
			
		||||
    "content-hash": "dc897c0ab21d662a65b3818331edd2f2",
 | 
			
		||||
    "packages": [
 | 
			
		||||
        {
 | 
			
		||||
            "name": "netresearch/jsonmapper",
 | 
			
		||||
@ -372,16 +372,16 @@
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "phpunit/php-code-coverage",
 | 
			
		||||
            "version": "11.0.3",
 | 
			
		||||
            "version": "11.0.4",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
 | 
			
		||||
                "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92"
 | 
			
		||||
                "reference": "4dc2b7a606073f0fb80da09842ffb068b627c38f"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e35a2cbcabac0e6865fd373742ea432a3c34f92",
 | 
			
		||||
                "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92",
 | 
			
		||||
                "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4dc2b7a606073f0fb80da09842ffb068b627c38f",
 | 
			
		||||
                "reference": "4dc2b7a606073f0fb80da09842ffb068b627c38f",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
@ -438,7 +438,7 @@
 | 
			
		||||
            "support": {
 | 
			
		||||
                "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues",
 | 
			
		||||
                "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy",
 | 
			
		||||
                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.3"
 | 
			
		||||
                "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.4"
 | 
			
		||||
            },
 | 
			
		||||
            "funding": [
 | 
			
		||||
                {
 | 
			
		||||
@ -446,7 +446,7 @@
 | 
			
		||||
                    "type": "github"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2024-03-12T15:35:40+00:00"
 | 
			
		||||
            "time": "2024-06-29T08:26:25+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "phpunit/php-file-iterator",
 | 
			
		||||
@ -1716,6 +1716,54 @@
 | 
			
		||||
            ],
 | 
			
		||||
            "time": "2024-02-02T06:10:47+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "square/pjson",
 | 
			
		||||
            "version": "v0.5.0",
 | 
			
		||||
            "source": {
 | 
			
		||||
                "type": "git",
 | 
			
		||||
                "url": "https://github.com/square/pjson.git",
 | 
			
		||||
                "reference": "cf9f9a7810ad7287b30658f60c0bbbba80217319"
 | 
			
		||||
            },
 | 
			
		||||
            "dist": {
 | 
			
		||||
                "type": "zip",
 | 
			
		||||
                "url": "https://api.github.com/repos/square/pjson/zipball/cf9f9a7810ad7287b30658f60c0bbbba80217319",
 | 
			
		||||
                "reference": "cf9f9a7810ad7287b30658f60c0bbbba80217319",
 | 
			
		||||
                "shasum": ""
 | 
			
		||||
            },
 | 
			
		||||
            "require": {
 | 
			
		||||
                "php": ">=8.0"
 | 
			
		||||
            },
 | 
			
		||||
            "require-dev": {
 | 
			
		||||
                "orchestra/testbench": "^7.11",
 | 
			
		||||
                "phpstan/phpstan": "^1.8",
 | 
			
		||||
                "phpunit/phpunit": "^9.5",
 | 
			
		||||
                "squizlabs/php_codesniffer": "^3.7",
 | 
			
		||||
                "symfony/var-dumper": "^6.0"
 | 
			
		||||
            },
 | 
			
		||||
            "type": "library",
 | 
			
		||||
            "autoload": {
 | 
			
		||||
                "psr-4": {
 | 
			
		||||
                    "Square\\Pjson\\": "src/",
 | 
			
		||||
                    "Square\\Pjson\\Tests\\": "tests/"
 | 
			
		||||
                }
 | 
			
		||||
            },
 | 
			
		||||
            "notification-url": "https://packagist.org/downloads/",
 | 
			
		||||
            "license": [
 | 
			
		||||
                "Apache-2.0"
 | 
			
		||||
            ],
 | 
			
		||||
            "authors": [
 | 
			
		||||
                {
 | 
			
		||||
                    "name": "Seb",
 | 
			
		||||
                    "email": "sebastien@squareup.com"
 | 
			
		||||
                }
 | 
			
		||||
            ],
 | 
			
		||||
            "description": "Library for JSON <=> PHP model serialization / deserialization. Deserialize JSON directly into your object model PHP classes.",
 | 
			
		||||
            "support": {
 | 
			
		||||
                "issues": "https://github.com/square/pjson/issues",
 | 
			
		||||
                "source": "https://github.com/square/pjson/tree/v0.5.0"
 | 
			
		||||
            },
 | 
			
		||||
            "time": "2024-03-15T18:19:22+00:00"
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "name": "theseer/tokenizer",
 | 
			
		||||
            "version": "1.2.3",
 | 
			
		||||
 | 
			
		||||
@ -3,8 +3,8 @@
 | 
			
		||||
namespace BitBadger\PDODocument\Mapper;
 | 
			
		||||
 | 
			
		||||
use BitBadger\PDODocument\DocumentException;
 | 
			
		||||
use Exception;
 | 
			
		||||
use JsonMapper;
 | 
			
		||||
use JsonMapper_Exception;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Map domain class instances from JSON documents
 | 
			
		||||
@ -32,12 +32,15 @@ class DocumentMapper implements Mapper
 | 
			
		||||
    public function map(array $result): mixed
 | 
			
		||||
    {
 | 
			
		||||
        try {
 | 
			
		||||
            if (method_exists($this->className, 'fromJsonString')) {
 | 
			
		||||
                return $this->className::fromJsonString($result[$this->fieldName]);
 | 
			
		||||
            }
 | 
			
		||||
            $json = json_decode($result[$this->fieldName]);
 | 
			
		||||
            if (is_null($json)) {
 | 
			
		||||
                throw new DocumentException("Could not map document for $this->className: " . json_last_error_msg());
 | 
			
		||||
            }
 | 
			
		||||
            return (new JsonMapper())->map($json, $this->className);
 | 
			
		||||
        } catch (JsonMapper_Exception $ex) {
 | 
			
		||||
        } catch (Exception $ex) {
 | 
			
		||||
            throw new DocumentException("Could not map document for $this->className", previous: $ex);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,10 @@ class Parameters
 | 
			
		||||
     */
 | 
			
		||||
    public static function json(string $name, object|array $document): array
 | 
			
		||||
    {
 | 
			
		||||
        return [$name => json_encode($document, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)];
 | 
			
		||||
        return [$name => match (is_object($document) && method_exists($document, 'toJson')) {
 | 
			
		||||
            true  => $document->toJson(),
 | 
			
		||||
            false => json_encode($document, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)
 | 
			
		||||
        }];
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										16
									
								
								tests/PjsonDocument.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								tests/PjsonDocument.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,16 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Test;
 | 
			
		||||
 | 
			
		||||
use Square\Pjson\{Json, JsonSerialize};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A test document annotated with pjson attributes using the `JsonSerialize` trait
 | 
			
		||||
 */
 | 
			
		||||
class PjsonDocument
 | 
			
		||||
{
 | 
			
		||||
    use JsonSerialize;
 | 
			
		||||
 | 
			
		||||
    public function __construct(#[Json] public PjsonId $id = new PjsonId(''), #[Json] public string $name = '',
 | 
			
		||||
                                #[Json('num_value')] public int $numValue = 0, public string $skipped = 'yep') { }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										23
									
								
								tests/PjsonId.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								tests/PjsonId.php
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,23 @@
 | 
			
		||||
<?php declare(strict_types=1);
 | 
			
		||||
 | 
			
		||||
namespace Test;
 | 
			
		||||
 | 
			
		||||
use Square\Pjson\JsonDataSerializable;
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * A serializable ID wrapper class
 | 
			
		||||
 */
 | 
			
		||||
class PjsonId implements JsonDataSerializable
 | 
			
		||||
{
 | 
			
		||||
    public function __construct(protected string $value) { }
 | 
			
		||||
 | 
			
		||||
    public function toJsonData(): string
 | 
			
		||||
    {
 | 
			
		||||
        return $this->value;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public static function fromJsonData($jd, array|string $path = []): static
 | 
			
		||||
    {
 | 
			
		||||
        return new static($jd);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
@ -6,6 +6,7 @@ use BitBadger\PDODocument\{DocumentException, Field};
 | 
			
		||||
use BitBadger\PDODocument\Mapper\DocumentMapper;
 | 
			
		||||
use PHPUnit\Framework\Attributes\TestDox;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
use Test\{PjsonDocument, PjsonId};
 | 
			
		||||
 | 
			
		||||
// ** Test class hierarchy for serialization **
 | 
			
		||||
 | 
			
		||||
@ -48,10 +49,28 @@ class DocumentMapperTest extends TestCase
 | 
			
		||||
        $this->assertEquals('tester', $doc->subDoc->name, 'Sub-document name not filled correctly');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[TestDox('Map succeeds with valid JSON for pjson class')]
 | 
			
		||||
    public function testMapSucceedsWithValidJSONForPjsonClass(): void
 | 
			
		||||
    {
 | 
			
		||||
        $doc = (new DocumentMapper(PjsonDocument::class))->map(['data' => '{"id":"seven","name":"bob","num_value":8}']);
 | 
			
		||||
        $this->assertNotNull($doc, 'The document should not have been null');
 | 
			
		||||
        $this->assertEquals(new PjsonId('seven'), $doc->id, 'ID not filled correctly');
 | 
			
		||||
        $this->assertEquals('bob', $doc->name, 'Name not filled correctly');
 | 
			
		||||
        $this->assertEquals(8, $doc->numValue, 'Numeric value not filled correctly');
 | 
			
		||||
        $this->assertFalse(isset($doc->skipped), 'Non-JSON field has not been set');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[TestDox('Map fails with invalid JSON')]
 | 
			
		||||
    public function testMapFailsWithInvalidJSON(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->expectException(DocumentException::class);
 | 
			
		||||
        (new DocumentMapper(TestDocument::class))->map(['data' => 'this is not valid']);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[TestDox('Map fails with invalid JSON for pjson class')]
 | 
			
		||||
    public function testMapFailsWithInvalidJSONForPjsonClass(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->expectException(DocumentException::class);
 | 
			
		||||
        (new DocumentMapper(PjsonDocument::class))->map(['data' => 'not even close']);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,8 @@ namespace Test\Unit;
 | 
			
		||||
use BitBadger\PDODocument\{Configuration, DocumentException, Field, Mode, Parameters};
 | 
			
		||||
use PHPUnit\Framework\Attributes\TestDox;
 | 
			
		||||
use PHPUnit\Framework\TestCase;
 | 
			
		||||
use stdClass;
 | 
			
		||||
use Test\{PjsonDocument, PjsonId};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Unit tests for the Parameters class
 | 
			
		||||
@ -24,13 +26,31 @@ class ParametersTest extends TestCase
 | 
			
		||||
        $this->assertEquals([':id' => '7'], Parameters::id(7), 'ID parameter not constructed correctly');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testJsonSucceeds(): void
 | 
			
		||||
    public function testJsonSucceedsForArray(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->assertEquals([':it' => '{"id":18,"url":"https://www.unittest.com"}'],
 | 
			
		||||
            Parameters::json(':it', ['id' => 18, 'url' => 'https://www.unittest.com']),
 | 
			
		||||
            'JSON parameter not constructed correctly');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    #[TestDox('json succeeds for stdClass')]
 | 
			
		||||
    public function testJsonSucceedsForStdClass(): void
 | 
			
		||||
    {
 | 
			
		||||
        $obj      = new stdClass();
 | 
			
		||||
        $obj->id  = 19;
 | 
			
		||||
        $obj->url = 'https://testhere.info';
 | 
			
		||||
        $this->assertEquals([':it' => '{"id":19,"url":"https://testhere.info"}'], Parameters::json(':it', $obj),
 | 
			
		||||
            'JSON parameter not constructed correctly');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    public function testJsonSucceedsForPjsonClass(): void
 | 
			
		||||
    {
 | 
			
		||||
        $this->assertEquals([':it' => '{"id":"999","name":"a test","num_value":98}'],
 | 
			
		||||
            Parameters::json(':it', new PjsonDocument(new PjsonId('999'), 'a test', 98, 'nothing')),
 | 
			
		||||
            'JSON parameter not constructed correctly');
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
    public function testNameFieldsSucceeds(): void
 | 
			
		||||
    {
 | 
			
		||||
        $named = Parameters::nameFields([Field::EQ('it', 17), Field::EQ('also', 22, ':also'), Field::EQ('other', 24)]);
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user