Something went wrong. Try again.
Parse and validate AT Protocol Lexicons with DTO generation for Laravel
Something went wrong. Try again.
8.7 kB · 346 lines
PHP
at dev
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347<?php
namespace SocialDept\AtpSchema\Tests\Unit\Data;
use Orchestra\Testbench\TestCase;use SocialDept\AtpSchema\Data\Data;
class DataTest extends TestCase{ public function test_it_converts_to_array(): void { $data = new TestData('John', 30);
$array = $data->toArray();
$this->assertSame([ 'name' => 'John', 'age' => 30, ], $array); }
public function test_it_converts_to_json(): void { $data = new TestData('John', 30);
$json = $data->toJson();
$this->assertJson($json); $this->assertSame('{"name":"John","age":30}', $json); }
public function test_it_is_json_serializable(): void { $data = new TestData('John', 30);
$json = json_encode($data);
$this->assertSame('{"name":"John","age":30}', $json); }
public function test_it_converts_to_string(): void { $data = new TestData('John', 30);
$string = (string) $data;
$this->assertSame('{"name":"John","age":30}', $string); }
public function test_it_creates_from_array(): void { $data = TestData::fromArray([ 'name' => 'Jane', 'age' => 25, ]);
$this->assertSame('Jane', $data->name); $this->assertSame(25, $data->age); }
public function test_it_creates_from_json(): void { $data = TestData::fromJson('{"name":"Bob","age":40}');
$this->assertSame('Bob', $data->name); $this->assertSame(40, $data->age); }
public function test_it_throws_on_invalid_json(): void { $this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('Invalid JSON');
TestData::fromJson('{invalid json}'); }
public function test_it_creates_from_record(): void { $data = TestData::fromRecord([ 'name' => 'Alice', 'age' => 35, ]);
$this->assertSame('Alice', $data->name); $this->assertSame(35, $data->age); }
public function test_it_converts_to_record(): void { $data = new TestData('John', 30);
$record = $data->toRecord();
$this->assertSame([ 'name' => 'John', 'age' => 30, '$type' => 'app.test.data', ], $record); }
public function test_it_checks_equality(): void { $data1 = new TestData('John', 30); $data2 = new TestData('John', 30); $data3 = new TestData('Jane', 25);
$this->assertTrue($data1->equals($data2)); $this->assertFalse($data1->equals($data3)); }
public function test_it_generates_hash(): void { $data = new TestData('John', 30);
$hash = $data->hash();
$this->assertIsString($hash); $this->assertSame(64, strlen($hash)); // SHA256 produces 64 hex characters }
public function test_it_generates_same_hash_for_equal_data(): void { $data1 = new TestData('John', 30); $data2 = new TestData('John', 30);
$this->assertSame($data1->hash(), $data2->hash()); }
public function test_it_generates_different_hash_for_different_data(): void { $data1 = new TestData('John', 30); $data2 = new TestData('Jane', 25);
$this->assertNotSame($data1->hash(), $data2->hash()); }
public function test_it_gets_property_dynamically(): void { $data = new TestData('John', 30);
$this->assertSame('John', $data->__get('name')); $this->assertSame(30, $data->__get('age')); }
public function test_it_throws_on_nonexistent_property(): void { $data = new TestData('John', 30);
$this->expectException(\InvalidArgumentException::class); $this->expectExceptionMessage('Property nonexistent does not exist');
$data->__get('nonexistent'); }
public function test_it_checks_if_property_exists(): void { $data = new TestData('John', 30);
$this->assertTrue($data->__isset('name')); $this->assertTrue($data->__isset('age')); $this->assertFalse($data->__isset('nonexistent')); }
public function test_it_clones_with_modified_properties(): void { $data = new TestData('John', 30);
$modified = $data->with(['age' => 31]);
$this->assertSame('John', $modified->name); $this->assertSame(31, $modified->age); $this->assertNotSame($data, $modified); $this->assertSame(30, $data->age); // Original unchanged }
public function test_it_serializes_nested_data_objects(): void { $nested = new TestData('Inner', 20); $parent = new TestDataWithNested('Outer', $nested);
$array = $parent->toArray();
$this->assertSame([ 'name' => 'Outer', 'nested' => [ 'name' => 'Inner', 'age' => 20, '$type' => 'app.test.data', ], ], $array); }
public function test_it_serializes_arrays_of_data_objects(): void { $items = [ new TestData('First', 10), new TestData('Second', 20), ]; $collection = new TestDataWithArray('Collection', $items);
$array = $collection->toArray();
$this->assertSame([ 'name' => 'Collection', 'items' => [ ['name' => 'First', 'age' => 10, '$type' => 'app.test.data'], ['name' => 'Second', 'age' => 20, '$type' => 'app.test.data'], ], ], $array); }
public function test_it_serializes_datetime_objects(): void { $date = new \DateTime('2024-01-01T12:00:00Z'); $data = new TestDataWithDate('Event', $date);
$array = $data->toArray();
$this->assertArrayHasKey('createdAt', $array); $this->assertIsString($array['createdAt']); $this->assertStringContainsString('2024-01-01', $array['createdAt']); }
public function test_it_returns_lexicon_nsid(): void { $lexicon = TestData::getLexicon();
$this->assertSame('app.test.data', $lexicon); }
public function test_validation_returns_true_when_helper_not_available(): void { $data = new TestData('John', 30);
// Schema helper may not be available in unit tests $result = $data->validate();
$this->assertTrue($result); }
public function test_validation_errors_returns_empty_when_helper_not_available(): void { $data = new TestData('John', 30);
// Schema helper may not be available in unit tests $errors = $data->validateWithErrors();
$this->assertIsArray($errors); }}
// Test implementations
class TestData extends Data{ public function __construct( public readonly string $name, public readonly int $age ) { }
public static function getLexicon(): string { return 'app.test.data'; }
public static function fromArray(array $data): static { return new static( name: $data['name'], age: $data['age'] ); }}
class TestDataWithNested extends Data{ public function __construct( public readonly string $name, public readonly TestData $nested ) { }
public static function getLexicon(): string { return 'app.test.nested'; }
public static function fromArray(array $data): static { return new static( name: $data['name'], nested: TestData::fromArray($data['nested']) ); }}
class TestDataWithArray extends Data{ /** * @param array<TestData> $items */ public function __construct( public readonly string $name, public readonly array $items ) { }
public static function getLexicon(): string { return 'app.test.collection'; }
public static function fromArray(array $data): static { return new static( name: $data['name'], items: array_map( fn ($item) => TestData::fromArray($item), $data['items'] ) ); }}
class TestDataWithDate extends Data{ public function __construct( public readonly string $name, public readonly \DateTimeInterface $createdAt ) { }
public static function getLexicon(): string { return 'app.test.dated'; }
public static function fromArray(array $data): static { return new static( name: $data['name'], createdAt: new \DateTime($data['createdAt']) ); }}