Changeset 63299
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/ai-client/class-wp-ai-client-prompt-builder.php
r63298 r63299 227 227 228 228 /** 229 * Clones the wrapped prompt builder alongside this instance. 230 * 231 * The wrapped builder mutates its own state, so without this a clone would 232 * share that state with the original and any change made to one would be 233 * visible in the other. 234 * 235 * @since 7.2.0 236 */ 237 public function __clone() { 238 $this->builder = clone $this->builder; 239 240 if ( null !== $this->error ) { 241 $this->error = clone $this->error; 242 } 243 } 244 245 /** 229 246 * Registers WordPress abilities as function declarations for the AI model. 230 247 * -
trunk/tests/phpunit/tests/ai-client/wpAiClientPromptBuilder.php
r63298 r63299 2615 2615 2616 2616 /** 2617 * Returns the text of every message part held by a prompt builder. 2618 * 2619 * @param WP_AI_Client_Prompt_Builder $builder The prompt builder to read. 2620 * @return string[] The text of each message part, in order. 2621 */ 2622 private function get_prompt_parts( WP_AI_Client_Prompt_Builder $builder ): array { 2623 $wrapped = new ReflectionProperty( WP_AI_Client_Prompt_Builder::class, 'builder' ); 2624 self::set_accessible( $wrapped ); 2625 $inner = $wrapped->getValue( $builder ); 2626 2627 $messages = new ReflectionProperty( $inner, 'messages' ); 2628 self::set_accessible( $messages ); 2629 2630 $parts = array(); 2631 foreach ( $messages->getValue( $inner ) as $message ) { 2632 foreach ( $message->getParts() as $part ) { 2633 $parts[] = (string) $part->getText(); 2634 } 2635 } 2636 2637 return $parts; 2638 } 2639 2640 /** 2641 * Tests that a clone does not share the wrapped builder with the original. 2642 * 2643 * @ticket 65782 2644 */ 2645 public function test_clone_does_not_share_the_wrapped_builder() { 2646 $builder = new WP_AI_Client_Prompt_Builder( AiClient::defaultRegistry(), 'Original prompt' ); 2647 $clone = clone $builder; 2648 2649 $wrapped = new ReflectionProperty( WP_AI_Client_Prompt_Builder::class, 'builder' ); 2650 self::set_accessible( $wrapped ); 2651 2652 $this->assertNotSame( 2653 $wrapped->getValue( $builder ), 2654 $wrapped->getValue( $clone ), 2655 'A clone should wrap its own builder instance' 2656 ); 2657 2658 $clone->with_text( 'Added to the clone' ); 2659 2660 $this->assertSame( array( 'Original prompt' ), $this->get_prompt_parts( $builder ), 'Changing the clone should not change the original' ); 2661 } 2662 2663 /** 2664 * Tests that the clone passed to the prevent prompt filter cannot change the prompt. 2665 * 2666 * @ticket 65782 2667 */ 2668 public function test_prevent_prompt_filter_cannot_mutate_the_original_prompt() { 2669 add_filter( 2670 'wp_ai_client_prevent_prompt', 2671 static function ( $prevent, $builder ) { 2672 $builder->with_text( 'Added by the filter' ); 2673 return $prevent; 2674 }, 2675 10, 2676 2 2677 ); 2678 2679 $builder = new WP_AI_Client_Prompt_Builder( AiClient::defaultRegistry(), 'Original prompt' ); 2680 $builder->is_supported(); 2681 2682 $this->assertSame( array( 'Original prompt' ), $this->get_prompt_parts( $builder ), 'A filter should not be able to change the prompt' ); 2683 } 2684 2685 /** 2617 2686 * Tests that once in error state, subsequent fluent calls return the same instance. 2618 2687 *
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)