Parse and validate AT Protocol Lexicons with DTO generation for Laravel
at dev 4.6 kB view raw
1<?php 2 3namespace SocialDept\AtpSchema\Tests\Unit\Parser; 4 5use Orchestra\Testbench\TestCase; 6use SocialDept\AtpSchema\Data\Types\ArrayType; 7use SocialDept\AtpSchema\Data\Types\BlobType; 8use SocialDept\AtpSchema\Data\Types\ObjectType; 9use SocialDept\AtpSchema\Data\Types\RefType; 10use SocialDept\AtpSchema\Data\Types\StringType; 11use SocialDept\AtpSchema\Data\Types\UnionType; 12use SocialDept\AtpSchema\Exceptions\TypeResolutionException; 13use SocialDept\AtpSchema\Parser\ComplexTypeParser; 14 15class ComplexTypeParserTest extends TestCase 16{ 17 protected ComplexTypeParser $parser; 18 19 protected function setUp(): void 20 { 21 parent::setUp(); 22 23 $this->parser = new ComplexTypeParser(); 24 } 25 26 public function test_it_parses_object_type(): void 27 { 28 $type = $this->parser->parse(['type' => 'object']); 29 30 $this->assertInstanceOf(ObjectType::class, $type); 31 } 32 33 public function test_it_parses_object_with_properties(): void 34 { 35 $type = $this->parser->parse([ 36 'type' => 'object', 37 'properties' => [ 38 'name' => ['type' => 'string'], 39 'age' => ['type' => 'integer'], 40 ], 41 ]); 42 43 $this->assertInstanceOf(ObjectType::class, $type); 44 $this->assertCount(2, $type->properties); 45 $this->assertInstanceOf(StringType::class, $type->properties['name']); 46 } 47 48 public function test_it_parses_array_type(): void 49 { 50 $type = $this->parser->parse(['type' => 'array']); 51 52 $this->assertInstanceOf(ArrayType::class, $type); 53 } 54 55 public function test_it_parses_array_with_items(): void 56 { 57 $type = $this->parser->parse([ 58 'type' => 'array', 59 'items' => ['type' => 'string'], 60 ]); 61 62 $this->assertInstanceOf(ArrayType::class, $type); 63 $this->assertInstanceOf(StringType::class, $type->items); 64 } 65 66 public function test_it_parses_nested_complex_types(): void 67 { 68 $type = $this->parser->parse([ 69 'type' => 'object', 70 'properties' => [ 71 'items' => [ 72 'type' => 'array', 73 'items' => ['type' => 'string'], 74 ], 75 ], 76 ]); 77 78 $this->assertInstanceOf(ObjectType::class, $type); 79 $this->assertInstanceOf(ArrayType::class, $type->properties['items']); 80 $this->assertInstanceOf(StringType::class, $type->properties['items']->items); 81 } 82 83 public function test_it_parses_union_type(): void 84 { 85 $type = $this->parser->parse([ 86 'type' => 'union', 87 'refs' => ['#typeA', '#typeB'], 88 ]); 89 90 $this->assertInstanceOf(UnionType::class, $type); 91 } 92 93 public function test_it_parses_ref_type(): void 94 { 95 $type = $this->parser->parse([ 96 'type' => 'ref', 97 'ref' => '#main', 98 ]); 99 100 $this->assertInstanceOf(RefType::class, $type); 101 } 102 103 public function test_it_parses_blob_type(): void 104 { 105 $type = $this->parser->parse([ 106 'type' => 'blob', 107 'accept' => ['image/*'], 108 ]); 109 110 $this->assertInstanceOf(BlobType::class, $type); 111 } 112 113 public function test_it_throws_on_missing_type(): void 114 { 115 $this->expectException(TypeResolutionException::class); 116 $this->expectExceptionMessage('Unknown Lexicon type: (missing type field)'); 117 118 $this->parser->parse([]); 119 } 120 121 public function test_it_throws_on_unknown_type(): void 122 { 123 $this->expectException(TypeResolutionException::class); 124 $this->expectExceptionMessage('Unknown Lexicon type: nonexistent'); 125 126 $this->parser->parse(['type' => 'nonexistent']); 127 } 128 129 public function test_it_checks_if_type_is_complex(): void 130 { 131 $this->assertTrue($this->parser->isComplex('object')); 132 $this->assertTrue($this->parser->isComplex('array')); 133 $this->assertTrue($this->parser->isComplex('union')); 134 $this->assertTrue($this->parser->isComplex('ref')); 135 $this->assertTrue($this->parser->isComplex('blob')); 136 137 $this->assertFalse($this->parser->isComplex('string')); 138 $this->assertFalse($this->parser->isComplex('integer')); 139 } 140 141 public function test_it_returns_supported_types(): void 142 { 143 $types = $this->parser->getSupportedTypes(); 144 145 $this->assertCount(5, $types); 146 $this->assertContains('object', $types); 147 $this->assertContains('array', $types); 148 $this->assertContains('union', $types); 149 $this->assertContains('ref', $types); 150 $this->assertContains('blob', $types); 151 } 152}