|
19 | 19 | use WordPress\AiClient\Providers\Models\Contracts\ModelInterface; |
20 | 20 | use WordPress\AiClient\Providers\Models\DTO\ModelConfig; |
21 | 21 | use WordPress\AiClient\Providers\Models\DTO\ModelMetadata; |
| 22 | +use WordPress\AiClient\Providers\Models\DTO\ModelRequirements; |
22 | 23 | use WordPress\AiClient\Providers\Models\ImageGeneration\Contracts\ImageGenerationModelInterface; |
23 | 24 | use WordPress\AiClient\Providers\Models\SpeechGeneration\Contracts\SpeechGenerationModelInterface; |
24 | 25 | use WordPress\AiClient\Providers\Models\TextGeneration\Contracts\TextGenerationModelInterface; |
@@ -613,6 +614,26 @@ public function testUsingModel(): void |
613 | 614 | $this->assertSame($model, $actualModel); |
614 | 615 | } |
615 | 616 |
|
| 617 | + /** |
| 618 | + * Tests usingProvider method. |
| 619 | + * |
| 620 | + * @return void |
| 621 | + */ |
| 622 | + public function testUsingProvider(): void |
| 623 | + { |
| 624 | + $builder = new PromptBuilder($this->registry); |
| 625 | + $result = $builder->usingProvider('test-provider'); |
| 626 | + |
| 627 | + $this->assertSame($builder, $result); |
| 628 | + |
| 629 | + $reflection = new \ReflectionClass($builder); |
| 630 | + $providerProperty = $reflection->getProperty('providerIdOrClassName'); |
| 631 | + $providerProperty->setAccessible(true); |
| 632 | + |
| 633 | + $actualProvider = $providerProperty->getValue($builder); |
| 634 | + $this->assertEquals('test-provider', $actualProvider); |
| 635 | + } |
| 636 | + |
616 | 637 | /** |
617 | 638 | * Tests usingSystemInstruction method. |
618 | 639 | * |
@@ -2462,4 +2483,119 @@ public function testIsSupportedForSpeechGeneration(): void |
2462 | 2483 |
|
2463 | 2484 | $this->assertTrue($builder->isSupportedForSpeechGeneration()); |
2464 | 2485 | } |
| 2486 | + |
| 2487 | + /** |
| 2488 | + * Tests generateResult with provider specified. |
| 2489 | + * |
| 2490 | + * @return void |
| 2491 | + */ |
| 2492 | + public function testGenerateResultWithProvider(): void |
| 2493 | + { |
| 2494 | + $result = $this->createMock(GenerativeAiResult::class); |
| 2495 | + |
| 2496 | + $modelMetadata = $this->createMock(ModelMetadata::class); |
| 2497 | + $modelMetadata->method('getId')->willReturn('provider-model'); |
| 2498 | + $modelMetadata->method('meetsRequirements')->willReturn(true); |
| 2499 | + |
| 2500 | + $model = $this->createTextGenerationModel($modelMetadata, $result); |
| 2501 | + |
| 2502 | + // Mock the registry to return the model when provider is specified |
| 2503 | + $this->registry->expects($this->once()) |
| 2504 | + ->method('findProviderModelsMetadataForSupport') |
| 2505 | + ->with('test-provider', $this->isInstanceOf(ModelRequirements::class)) |
| 2506 | + ->willReturn([$modelMetadata]); |
| 2507 | + |
| 2508 | + $this->registry->expects($this->once()) |
| 2509 | + ->method('getProviderModel') |
| 2510 | + ->with('test-provider', 'provider-model', $this->isInstanceOf(ModelConfig::class)) |
| 2511 | + ->willReturn($model); |
| 2512 | + |
| 2513 | + $builder = new PromptBuilder($this->registry, 'Test prompt'); |
| 2514 | + $builder->usingProvider('test-provider'); |
| 2515 | + |
| 2516 | + $actualResult = $builder->generateResult(); |
| 2517 | + $this->assertSame($result, $actualResult); |
| 2518 | + } |
| 2519 | + |
| 2520 | + /** |
| 2521 | + * Tests generateResult with provider but no suitable models. |
| 2522 | + * |
| 2523 | + * @return void |
| 2524 | + */ |
| 2525 | + public function testGenerateResultWithProviderNoModelsThrowsException(): void |
| 2526 | + { |
| 2527 | + // Mock the registry to return empty array when provider is specified |
| 2528 | + $this->registry->expects($this->once()) |
| 2529 | + ->method('findProviderModelsMetadataForSupport') |
| 2530 | + ->with('test-provider', $this->isInstanceOf(ModelRequirements::class)) |
| 2531 | + ->willReturn([]); |
| 2532 | + |
| 2533 | + $builder = new PromptBuilder($this->registry, 'Test prompt'); |
| 2534 | + $builder->usingProvider('test-provider'); |
| 2535 | + |
| 2536 | + $this->expectException(InvalidArgumentException::class); |
| 2537 | + $this->expectExceptionMessage('No models found that support the required capabilities'); |
| 2538 | + |
| 2539 | + $builder->generateResult(); |
| 2540 | + } |
| 2541 | + |
| 2542 | + /** |
| 2543 | + * Tests that provider takes precedence when both provider and model are set. |
| 2544 | + * |
| 2545 | + * @return void |
| 2546 | + */ |
| 2547 | + public function testModelTakesPrecedenceOverProvider(): void |
| 2548 | + { |
| 2549 | + $result = $this->createMock(GenerativeAiResult::class); |
| 2550 | + |
| 2551 | + $metadata = $this->createMock(ModelMetadata::class); |
| 2552 | + $metadata->method('getId')->willReturn('explicit-model'); |
| 2553 | + $metadata->method('meetsRequirements')->willReturn(true); |
| 2554 | + |
| 2555 | + $model = $this->createTextGenerationModel($metadata, $result); |
| 2556 | + |
| 2557 | + // Registry should not be called when model is explicitly set |
| 2558 | + $this->registry->expects($this->never()) |
| 2559 | + ->method('findProviderModelsMetadataForSupport'); |
| 2560 | + $this->registry->expects($this->never()) |
| 2561 | + ->method('getProviderModel'); |
| 2562 | + |
| 2563 | + $builder = new PromptBuilder($this->registry, 'Test prompt'); |
| 2564 | + $builder->usingProvider('test-provider'); |
| 2565 | + $builder->usingModel($model); // Model overrides provider |
| 2566 | + |
| 2567 | + $actualResult = $builder->generateResult(); |
| 2568 | + $this->assertSame($result, $actualResult); |
| 2569 | + } |
| 2570 | + |
| 2571 | + /** |
| 2572 | + * Tests fluent interface with provider. |
| 2573 | + * |
| 2574 | + * @return void |
| 2575 | + */ |
| 2576 | + public function testFluentInterfaceWithProvider(): void |
| 2577 | + { |
| 2578 | + $builder = new PromptBuilder($this->registry, 'Initial text'); |
| 2579 | + |
| 2580 | + $result = $builder |
| 2581 | + ->usingProvider('my-provider') |
| 2582 | + ->withText(' Additional text') |
| 2583 | + ->usingMaxTokens(500) |
| 2584 | + ->usingTemperature(0.7); |
| 2585 | + |
| 2586 | + $this->assertSame($builder, $result); |
| 2587 | + |
| 2588 | + $reflection = new \ReflectionClass($builder); |
| 2589 | + |
| 2590 | + $providerProperty = $reflection->getProperty('providerIdOrClassName'); |
| 2591 | + $providerProperty->setAccessible(true); |
| 2592 | + $this->assertEquals('my-provider', $providerProperty->getValue($builder)); |
| 2593 | + |
| 2594 | + $configProperty = $reflection->getProperty('modelConfig'); |
| 2595 | + $configProperty->setAccessible(true); |
| 2596 | + /** @var ModelConfig $config */ |
| 2597 | + $config = $configProperty->getValue($builder); |
| 2598 | + $this->assertEquals(500, $config->getMaxTokens()); |
| 2599 | + $this->assertEquals(0.7, $config->getTemperature()); |
| 2600 | + } |
2465 | 2601 | } |
0 commit comments