1919use PHPUnit \Framework \TestCase ;
2020use Symfony \AI \AiBundle \AiBundle ;
2121use Symfony \AI \Platform \Bridge \OpenAi \Embeddings ;
22+ use Symfony \AI \Store \Document \Loader \InMemoryLoader ;
23+ use Symfony \AI \Store \Document \Transformer \TextTrimTransformer ;
2224use Symfony \AI \Store \Document \Vectorizer ;
2325use Symfony \Component \Config \Definition \Exception \InvalidConfigurationException ;
2426use Symfony \Component \DependencyInjection \ContainerBuilder ;
@@ -678,6 +680,7 @@ public function testIndexerWithConfiguredVectorizer()
678680 ],
679681 'indexer ' => [
680682 'my_indexer ' => [
683+ 'loader ' => InMemoryLoader::class,
681684 'vectorizer ' => 'ai.vectorizer.my_vectorizer ' ,
682685 'store ' => 'ai.store.memory.my_store ' ,
683686 ],
@@ -691,15 +694,251 @@ public function testIndexerWithConfiguredVectorizer()
691694 $ indexerDefinition = $ container ->getDefinition ('ai.indexer.my_indexer ' );
692695 $ arguments = $ indexerDefinition ->getArguments ();
693696
694- // First argument should be a reference to the vectorizer
695697 $ this ->assertInstanceOf (Reference::class, $ arguments [0 ]);
696- $ this ->assertSame ('ai.vectorizer.my_vectorizer ' , (string ) $ arguments [0 ]);
698+ $ this ->assertSame (InMemoryLoader::class, (string ) $ arguments [0 ]);
699+
700+ $ this ->assertInstanceOf (Reference::class, $ arguments [1 ]);
701+ $ this ->assertSame ('ai.vectorizer.my_vectorizer ' , (string ) $ arguments [1 ]);
697702
698703 // Should not create model-specific vectorizer when using configured one
699704 $ this ->assertFalse ($ container ->hasDefinition ('ai.indexer.my_indexer.vectorizer ' ));
700705 $ this ->assertFalse ($ container ->hasDefinition ('ai.indexer.my_indexer.model ' ));
701706 }
702707
708+ public function testIndexerWithStringSource ()
709+ {
710+ $ container = $ this ->buildContainer ([
711+ 'ai ' => [
712+ 'store ' => [
713+ 'memory ' => [
714+ 'my_store ' => [],
715+ ],
716+ ],
717+ 'indexer ' => [
718+ 'my_indexer ' => [
719+ 'loader ' => InMemoryLoader::class,
720+ 'source ' => 'https://example.com/feed.xml ' ,
721+ 'vectorizer ' => 'my_vectorizer_service ' ,
722+ 'store ' => 'ai.store.memory.my_store ' ,
723+ ],
724+ ],
725+ ],
726+ ]);
727+
728+ $ this ->assertTrue ($ container ->hasDefinition ('ai.indexer.my_indexer ' ));
729+ $ indexerDefinition = $ container ->getDefinition ('ai.indexer.my_indexer ' );
730+ $ arguments = $ indexerDefinition ->getArguments ();
731+
732+ $ this ->assertSame ('https://example.com/feed.xml ' , $ arguments [3 ]);
733+ }
734+
735+ public function testIndexerWithArraySource ()
736+ {
737+ $ container = $ this ->buildContainer ([
738+ 'ai ' => [
739+ 'store ' => [
740+ 'memory ' => [
741+ 'my_store ' => [],
742+ ],
743+ ],
744+ 'indexer ' => [
745+ 'my_indexer ' => [
746+ 'loader ' => InMemoryLoader::class,
747+ 'source ' => [
748+ '/path/to/file1.txt ' ,
749+ '/path/to/file2.txt ' ,
750+ 'https://example.com/feed.xml ' ,
751+ ],
752+ 'vectorizer ' => 'my_vectorizer_service ' ,
753+ 'store ' => 'ai.store.memory.my_store ' ,
754+ ],
755+ ],
756+ ],
757+ ]);
758+
759+ $ this ->assertTrue ($ container ->hasDefinition ('ai.indexer.my_indexer ' ));
760+ $ indexerDefinition = $ container ->getDefinition ('ai.indexer.my_indexer ' );
761+ $ arguments = $ indexerDefinition ->getArguments ();
762+
763+ $ this ->assertIsArray ($ arguments [3 ]);
764+ $ this ->assertCount (3 , $ arguments [3 ]);
765+ $ this ->assertSame ([
766+ '/path/to/file1.txt ' ,
767+ '/path/to/file2.txt ' ,
768+ 'https://example.com/feed.xml ' ,
769+ ], $ arguments [3 ]);
770+ }
771+
772+ public function testIndexerWithNullSource ()
773+ {
774+ $ container = $ this ->buildContainer ([
775+ 'ai ' => [
776+ 'store ' => [
777+ 'memory ' => [
778+ 'my_store ' => [],
779+ ],
780+ ],
781+ 'indexer ' => [
782+ 'my_indexer ' => [
783+ 'loader ' => InMemoryLoader::class,
784+ 'vectorizer ' => 'my_vectorizer_service ' ,
785+ 'store ' => 'ai.store.memory.my_store ' ,
786+ // source not configured, should default to null
787+ ],
788+ ],
789+ ],
790+ ]);
791+
792+ $ this ->assertTrue ($ container ->hasDefinition ('ai.indexer.my_indexer ' ));
793+ $ indexerDefinition = $ container ->getDefinition ('ai.indexer.my_indexer ' );
794+ $ arguments = $ indexerDefinition ->getArguments ();
795+
796+ $ this ->assertNull ($ arguments [3 ]);
797+ }
798+
799+ public function testIndexerWithConfiguredTransformers ()
800+ {
801+ $ container = $ this ->buildContainer ([
802+ 'ai ' => [
803+ 'store ' => [
804+ 'memory ' => [
805+ 'my_store ' => [],
806+ ],
807+ ],
808+ 'indexer ' => [
809+ 'my_indexer ' => [
810+ 'loader ' => InMemoryLoader::class,
811+ 'transformers ' => [
812+ TextTrimTransformer::class,
813+ 'App\CustomTransformer ' ,
814+ ],
815+ 'vectorizer ' => 'my_vectorizer_service ' ,
816+ 'store ' => 'ai.store.memory.my_store ' ,
817+ ],
818+ ],
819+ ],
820+ ]);
821+
822+ $ this ->assertTrue ($ container ->hasDefinition ('ai.indexer.my_indexer ' ));
823+ $ indexerDefinition = $ container ->getDefinition ('ai.indexer.my_indexer ' );
824+ $ arguments = $ indexerDefinition ->getArguments ();
825+
826+ $ this ->assertIsArray ($ arguments [4 ]);
827+ $ this ->assertCount (2 , $ arguments [4 ]);
828+
829+ $ this ->assertInstanceOf (Reference::class, $ arguments [4 ][0 ]);
830+ $ this ->assertSame (TextTrimTransformer::class, (string ) $ arguments [4 ][0 ]);
831+
832+ $ this ->assertInstanceOf (Reference::class, $ arguments [4 ][1 ]);
833+ $ this ->assertSame ('App\CustomTransformer ' , (string ) $ arguments [4 ][1 ]);
834+ }
835+
836+ public function testIndexerWithEmptyTransformers ()
837+ {
838+ $ container = $ this ->buildContainer ([
839+ 'ai ' => [
840+ 'store ' => [
841+ 'memory ' => [
842+ 'my_store ' => [],
843+ ],
844+ ],
845+ 'indexer ' => [
846+ 'my_indexer ' => [
847+ 'loader ' => InMemoryLoader::class,
848+ 'transformers ' => [],
849+ 'vectorizer ' => 'my_vectorizer_service ' ,
850+ 'store ' => 'ai.store.memory.my_store ' ,
851+ ],
852+ ],
853+ ],
854+ ]);
855+
856+ $ this ->assertTrue ($ container ->hasDefinition ('ai.indexer.my_indexer ' ));
857+ $ indexerDefinition = $ container ->getDefinition ('ai.indexer.my_indexer ' );
858+ $ arguments = $ indexerDefinition ->getArguments ();
859+
860+ $ this ->assertSame ([], $ arguments [4 ]);
861+ }
862+
863+ public function testIndexerWithoutTransformers ()
864+ {
865+ $ container = $ this ->buildContainer ([
866+ 'ai ' => [
867+ 'store ' => [
868+ 'memory ' => [
869+ 'my_store ' => [],
870+ ],
871+ ],
872+ 'indexer ' => [
873+ 'my_indexer ' => [
874+ 'loader ' => InMemoryLoader::class,
875+ 'vectorizer ' => 'my_vectorizer_service ' ,
876+ 'store ' => 'ai.store.memory.my_store ' ,
877+ // transformers not configured, should default to empty array
878+ ],
879+ ],
880+ ],
881+ ]);
882+
883+ $ this ->assertTrue ($ container ->hasDefinition ('ai.indexer.my_indexer ' ));
884+ $ indexerDefinition = $ container ->getDefinition ('ai.indexer.my_indexer ' );
885+ $ arguments = $ indexerDefinition ->getArguments ();
886+
887+ $ this ->assertSame ([], $ arguments [4 ]);
888+ }
889+
890+ public function testIndexerWithSourceAndTransformers ()
891+ {
892+ $ container = $ this ->buildContainer ([
893+ 'ai ' => [
894+ 'store ' => [
895+ 'memory ' => [
896+ 'my_store ' => [],
897+ ],
898+ ],
899+ 'indexer ' => [
900+ 'my_indexer ' => [
901+ 'loader ' => InMemoryLoader::class,
902+ 'source ' => [
903+ '/path/to/file1.txt ' ,
904+ '/path/to/file2.txt ' ,
905+ ],
906+ 'transformers ' => [
907+ TextTrimTransformer::class,
908+ ],
909+ 'vectorizer ' => 'my_vectorizer_service ' ,
910+ 'store ' => 'ai.store.memory.my_store ' ,
911+ ],
912+ ],
913+ ],
914+ ]);
915+
916+ $ this ->assertTrue ($ container ->hasDefinition ('ai.indexer.my_indexer ' ));
917+ $ indexerDefinition = $ container ->getDefinition ('ai.indexer.my_indexer ' );
918+ $ arguments = $ indexerDefinition ->getArguments ();
919+
920+ $ this ->assertInstanceOf (Reference::class, $ arguments [0 ]);
921+ $ this ->assertSame (InMemoryLoader::class, (string ) $ arguments [0 ]);
922+
923+ $ this ->assertInstanceOf (Reference::class, $ arguments [1 ]);
924+ $ this ->assertSame ('my_vectorizer_service ' , (string ) $ arguments [1 ]);
925+
926+ $ this ->assertInstanceOf (Reference::class, $ arguments [2 ]);
927+ $ this ->assertSame ('ai.store.memory.my_store ' , (string ) $ arguments [2 ]);
928+
929+ $ this ->assertIsArray ($ arguments [3 ]);
930+ $ this ->assertCount (2 , $ arguments [3 ]);
931+ $ this ->assertSame ([
932+ '/path/to/file1.txt ' ,
933+ '/path/to/file2.txt ' ,
934+ ], $ arguments [3 ]);
935+
936+ $ this ->assertIsArray ($ arguments [4 ]);
937+ $ this ->assertCount (1 , $ arguments [4 ]);
938+ $ this ->assertInstanceOf (Reference::class, $ arguments [4 ][0 ]);
939+ $ this ->assertSame (TextTrimTransformer::class, (string ) $ arguments [4 ][0 ]);
940+ }
941+
703942 private function buildContainer (array $ configuration ): ContainerBuilder
704943 {
705944 $ container = new ContainerBuilder ();
@@ -959,6 +1198,7 @@ private function getFullConfig(): array
9591198 ],
9601199 'indexer ' => [
9611200 'my_text_indexer ' => [
1201+ 'loader ' => InMemoryLoader::class,
9621202 'vectorizer ' => 'ai.vectorizer.test_vectorizer ' ,
9631203 'store ' => 'my_azure_search_store_service_id ' ,
9641204 ],
0 commit comments