override = $override; } public function plugin_slug(): string { return 'test-adapter'; } public function detection_class(): string { return 'Test\\Adapter'; } public function detection_const(): string { return 'TEST_ADAPTER_VERSION'; } public function suitability_score(): array { return $this->compose_score( $this->override ); } }; } public function test_default_score_is_perfect_ten(): void { $score = $this->make_adapter()->suitability_score(); $this->assertSame( 10.0, $score['aggregate'] ); foreach ( array( 'd1_meta_calls', 'd2_meta_sql', 'd3_table_coverage', 'd4_registry_meta', 'd5_hook_bus', 'd6_options', 'd7_coupling', 'd8_perf' ) as $k ) { $this->assertSame( 1.0, $score[ $k ] ); } } public function test_partial_override_lowers_aggregate(): void { $score = $this->make_adapter( array( 'd5_hook_bus' => 0.5 ) )->suitability_score(); // 7 × 1.0 + 1 × 0.5 = 7.5; aggregate = 7.5 / 8 * 10 = 9.375 → rounded 9.38. $this->assertSame( 9.38, $score['aggregate'] ); } public function test_score_clamped_to_unit_interval(): void { $score = $this->make_adapter( array( 'd1_meta_calls' => 1.5, // → clamped to 1.0 'd2_meta_sql' => -0.3, // → clamped to 0.0 ) )->suitability_score(); $this->assertSame( 1.0, $score['d1_meta_calls'] ); $this->assertSame( 0.0, $score['d2_meta_sql'] ); } public function test_default_implementations_are_no_op(): void { $adapter = $this->make_adapter(); // All optional methods should be safe to invoke on a minimal adapter. $this->assertSame( array(), $adapter->migrations() ); $this->assertSame( '', $adapter->minimum_addon_version() ); $result = $adapter->doctor_check(); $this->assertTrue( $result['ok'] ); // Hook handlers must not throw on a no-op adapter. $adapter->on_register_query_hooks(); $adapter->on_register_event_hooks(); $adapter->on_register_entity_fields(); $this->assertTrue( true ); // reaching here = no exception } public function test_aggregate_rounding_is_two_decimals(): void { $score = $this->make_adapter( array( 'd1_meta_calls' => 0.85, 'd2_meta_sql' => 0.92, 'd3_table_coverage' => 0.78, ) )->suitability_score(); // All other dimensions stay at 1.0 → sum = 0.85+0.92+0.78+5*1.0 = 7.55. // aggregate = 7.55 / 8 * 10 = 9.4375 → round(2) = 9.44. $this->assertSame( 9.44, $score['aggregate'] ); } }