Parse and validate AT Protocol Lexicons with DTO generation for Laravel
at dev 6.1 kB view raw
1<?php 2 3namespace SocialDept\AtpSchema\Tests\Unit\Support; 4 5use Orchestra\Testbench\TestCase; 6use SocialDept\AtpSchema\Services\BlobHandler; 7use SocialDept\AtpSchema\Services\ModelMapper; 8use SocialDept\AtpSchema\Services\UnionResolver; 9use SocialDept\AtpSchema\Validation\Validator; 10 11class MacroableTest extends TestCase 12{ 13 protected function setUp(): void 14 { 15 parent::setUp(); 16 17 // Clear any existing macros 18 ModelMapper::flushMacros(); 19 BlobHandler::flushMacros(); 20 UnionResolver::flushMacros(); 21 Validator::flushMacros(); 22 } 23 24 public function test_model_mapper_supports_macros(): void 25 { 26 ModelMapper::macro('customMethod', fn () => 'custom result'); 27 28 $mapper = new ModelMapper(); 29 30 $this->assertEquals('custom result', $mapper->customMethod()); 31 } 32 33 public function test_model_mapper_macro_can_access_instance(): void 34 { 35 ModelMapper::macro('getCount', function () { 36 return $this->count(); 37 }); 38 39 $mapper = new ModelMapper(); 40 41 $this->assertEquals(0, $mapper->getCount()); 42 } 43 44 public function test_blob_handler_supports_macros(): void 45 { 46 BlobHandler::macro('customMethod', fn () => 'blob custom'); 47 48 $handler = new BlobHandler(); 49 50 $this->assertEquals('blob custom', $handler->customMethod()); 51 } 52 53 public function test_blob_handler_macro_can_access_instance(): void 54 { 55 BlobHandler::macro('getCurrentDisk', function () { 56 return $this->getDisk(); 57 }); 58 59 $handler = new BlobHandler('local'); 60 61 $this->assertEquals('local', $handler->getCurrentDisk()); 62 } 63 64 public function test_union_resolver_supports_macros(): void 65 { 66 UnionResolver::macro('customMethod', fn () => 'union custom'); 67 68 $resolver = new UnionResolver(); 69 70 $this->assertEquals('union custom', $resolver->customMethod()); 71 } 72 73 public function test_validator_supports_macros(): void 74 { 75 Validator::macro('customMethod', fn () => 'validator custom'); 76 77 $schemaLoader = $this->createMock(\SocialDept\AtpSchema\Parser\SchemaLoader::class); 78 $validator = new Validator($schemaLoader); 79 80 $this->assertEquals('validator custom', $validator->customMethod()); 81 } 82 83 public function test_macros_can_accept_parameters(): void 84 { 85 ModelMapper::macro('multiply', fn ($a, $b) => $a * $b); 86 87 $mapper = new ModelMapper(); 88 89 $this->assertEquals(15, $mapper->multiply(3, 5)); 90 } 91 92 public function test_macros_work_across_multiple_instances(): void 93 { 94 ModelMapper::macro('greet', fn ($name) => "Hello, {$name}!"); 95 96 $mapper1 = new ModelMapper(); 97 $mapper2 = new ModelMapper(); 98 99 $this->assertEquals('Hello, Alice!', $mapper1->greet('Alice')); 100 $this->assertEquals('Hello, Bob!', $mapper2->greet('Bob')); 101 } 102 103 public function test_macro_can_return_instance_for_chaining(): void 104 { 105 ModelMapper::macro('chainable', function () { 106 return $this; 107 }); 108 109 $mapper = new ModelMapper(); 110 111 $result = $mapper->chainable()->chainable(); 112 113 $this->assertSame($mapper, $result); 114 } 115 116 public function test_has_macro_checks_existence(): void 117 { 118 ModelMapper::macro('exists', fn () => true); 119 120 $this->assertTrue(ModelMapper::hasMacro('exists')); 121 $this->assertFalse(ModelMapper::hasMacro('doesNotExist')); 122 } 123 124 public function test_flush_macros_removes_all(): void 125 { 126 ModelMapper::macro('test1', fn () => 'result1'); 127 ModelMapper::macro('test2', fn () => 'result2'); 128 129 $this->assertTrue(ModelMapper::hasMacro('test1')); 130 $this->assertTrue(ModelMapper::hasMacro('test2')); 131 132 ModelMapper::flushMacros(); 133 134 $this->assertFalse(ModelMapper::hasMacro('test1')); 135 $this->assertFalse(ModelMapper::hasMacro('test2')); 136 } 137 138 public function test_macros_are_independent_between_classes(): void 139 { 140 ModelMapper::macro('sharedName', fn () => 'mapper'); 141 BlobHandler::macro('sharedName', fn () => 'handler'); 142 143 $mapper = new ModelMapper(); 144 $handler = new BlobHandler(); 145 146 $this->assertEquals('mapper', $mapper->sharedName()); 147 $this->assertEquals('handler', $handler->sharedName()); 148 } 149 150 public function test_macro_can_use_closure_variables(): void 151 { 152 $prefix = 'PREFIX'; 153 154 ModelMapper::macro('withPrefix', fn ($value) => "{$prefix}: {$value}"); 155 156 $mapper = new ModelMapper(); 157 158 $this->assertEquals('PREFIX: test', $mapper->withPrefix('test')); 159 } 160 161 public function test_macro_can_modify_instance_state(): void 162 { 163 BlobHandler::macro('switchDisk', function ($disk) { 164 $this->setDisk($disk); 165 166 return $this; 167 }); 168 169 $handler = new BlobHandler('local'); 170 171 $this->assertEquals('local', $handler->getDisk()); 172 173 $handler->switchDisk('s3'); 174 175 $this->assertEquals('s3', $handler->getDisk()); 176 } 177 178 public function test_mixin_adds_multiple_methods(): void 179 { 180 $mixin = new class () { 181 public function method1() 182 { 183 return fn () => 'method1'; 184 } 185 186 public function method2() 187 { 188 return fn () => 'method2'; 189 } 190 }; 191 192 ModelMapper::mixin($mixin); 193 194 $mapper = new ModelMapper(); 195 196 $this->assertEquals('method1', $mapper->method1()); 197 $this->assertEquals('method2', $mapper->method2()); 198 } 199 200 public function test_complex_macro_with_dependencies(): void 201 { 202 ModelMapper::macro('complexOperation', function ($data) { 203 // Use existing methods 204 $count = $this->count(); 205 206 return [ 207 'count' => $count, 208 'data' => strtoupper($data), 209 ]; 210 }); 211 212 $mapper = new ModelMapper(); 213 214 $result = $mapper->complexOperation('test'); 215 216 $this->assertEquals([ 217 'count' => 0, 218 'data' => 'TEST', 219 ], $result); 220 } 221}