newInstanceWithoutConstructor(); return $ref->getMethod('mergePatch')->invoke($instance, $existing, $incoming); } #[Test] public function list_in_existing_is_replaced_when_incoming_sends_a_map(): void { $existing = [ 'form' => [ 'fields' => [ ['name' => 'name', 'label' => 'Name'], ['name' => 'email', 'label' => 'Email'], ['name' => 'message', 'label' => 'Message'], ], ], ]; $incoming = [ 'form' => [ 'fields' => [ 'name' => ['label' => 'Name'], 'email' => ['label' => 'Email'], ], ], ]; $merged = $this->invoke($existing, $incoming); $this->assertSame(['name', 'email'], array_keys($merged['form']['fields'])); $yaml = Yaml::dump($merged, 10, 2); $this->assertStringNotContainsString("'0':", $yaml, 'No quoted integer keys should leak through'); $this->assertStringNotContainsString("'1':", $yaml); $this->assertStringNotContainsString("'2':", $yaml); } #[Test] public function list_in_incoming_replaces_existing_map(): void { $existing = [ 'form' => [ 'fields' => [ 'name' => ['label' => 'Name'], 'email' => ['label' => 'Email'], ], ], ]; $incoming = [ 'form' => [ 'fields' => [ ['name' => 'subject', 'label' => 'Subject'], ], ], ]; $merged = $this->invoke($existing, $incoming); $this->assertTrue(array_is_list($merged['form']['fields'])); $this->assertCount(1, $merged['form']['fields']); $this->assertSame('subject', $merged['form']['fields'][0]['name']); } #[Test] public function maps_still_recurse_so_partial_header_updates_keep_working(): void { $existing = [ 'title' => 'Old', 'metadata' => [ 'description' => 'desc', 'author' => 'andy', ], 'published' => true, ]; $incoming = [ 'metadata' => [ 'author' => 'someone', ], ]; $merged = $this->invoke($existing, $incoming); $this->assertSame('Old', $merged['title']); $this->assertSame('desc', $merged['metadata']['description']); $this->assertSame('someone', $merged['metadata']['author']); $this->assertTrue($merged['published']); } #[Test] public function nested_list_under_a_map_is_replaced_not_index_merged(): void { $existing = ['taxonomy' => ['tag' => ['a', 'b', 'c', 'd']]]; $incoming = ['taxonomy' => ['tag' => ['x', 'y']]]; $merged = $this->invoke($existing, $incoming); $this->assertSame(['x', 'y'], $merged['taxonomy']['tag']); } #[Test] public function quark2_issue_8_full_payload_round_trip(): void { $existing = [ 'title' => 'Contact', 'form' => [ 'name' => 'contact-form', 'fields' => [ ['name' => 'name', 'label' => 'Name', 'type' => 'text'], ['name' => 'email', 'label' => 'Email', 'type' => 'email'], ['name' => 'message', 'label' => 'Message', 'type' => 'textarea'], ], 'buttons' => [ ['type' => 'submit', 'value' => 'Submit'], ['type' => 'reset', 'value' => 'Reset'], ], 'process' => [ ['email' => ['from' => 'x', 'subject' => 'y']], ['save' => ['fileprefix' => 'feedback-']], ['message' => 'Thank you'], ['display' => '/contact'], ], ], ]; $incoming = [ 'form' => [ 'fields' => [ 'name' => ['label' => 'Name', 'type' => 'text'], 'email' => ['label' => 'Email', 'type' => 'email'], ], 'buttons' => [ 'submit' => ['type' => 'submit', 'value' => 'Submit'], ], 'process' => [ 'email' => ['from' => 'x', 'subject' => 'y'], 'message' => 'Thank you', ], ], ]; $merged = $this->invoke($existing, $incoming); $this->assertSame('Contact', $merged['title']); $this->assertSame('contact-form', $merged['form']['name']); $this->assertSame(['name', 'email'], array_keys($merged['form']['fields'])); $this->assertSame(['submit'], array_keys($merged['form']['buttons'])); $this->assertSame(['email', 'message'], array_keys($merged['form']['process'])); $yaml = Yaml::dump($merged, 10, 2); $this->assertStringNotContainsString("'0':", $yaml); $this->assertStringNotContainsString("'1':", $yaml); $this->assertStringNotContainsString("'2':", $yaml); $this->assertStringNotContainsString("'3':", $yaml); } }