|
| 1 | +import unittest |
| 2 | + |
| 3 | +from ravendb.documents.operations.ai.chunking_options import ChunkingOptions, ChunkingMethod |
| 4 | +from ravendb.documents.operations.ai.embedding_path_configuration import EmbeddingPathConfiguration |
| 5 | +from ravendb.documents.operations.ai.embeddings_generation_configuration import EmbeddingsGenerationConfiguration |
| 6 | +from ravendb.documents.operations.ai.embeddings_transformation import EmbeddingsTransformation |
| 7 | + |
| 8 | + |
| 9 | +def _config(**overrides) -> EmbeddingsGenerationConfiguration: |
| 10 | + # A base config that passes every check except the paths/transformation logic under test. |
| 11 | + base = dict( |
| 12 | + name="emb", |
| 13 | + identifier="emb", |
| 14 | + collection="Docs", |
| 15 | + connection_string_name="cs", |
| 16 | + chunking_options_for_querying=ChunkingOptions(ChunkingMethod.HTML_STRIP, 100, 0), |
| 17 | + ) |
| 18 | + base.update(overrides) |
| 19 | + return EmbeddingsGenerationConfiguration(**base) |
| 20 | + |
| 21 | + |
| 22 | +def _validate(config) -> list: |
| 23 | + return config.validate(validate_name=False, validate_identifier=False) |
| 24 | + |
| 25 | + |
| 26 | +class TestEmbeddingsGenerationConfigurationValidate(unittest.TestCase): |
| 27 | + def test_paths_and_transformation_together_are_allowed(self): |
| 28 | + # C# has no mutual-exclusivity rule; setting both must NOT be rejected client-side. |
| 29 | + config = _config( |
| 30 | + embeddings_path_configurations=[ |
| 31 | + EmbeddingPathConfiguration("Name", ChunkingOptions(ChunkingMethod.HTML_STRIP, 100, 0)) |
| 32 | + ], |
| 33 | + embeddings_transformation=EmbeddingsTransformation(script="embeddings.generate(this.Name)"), |
| 34 | + ) |
| 35 | + errors = _validate(config) |
| 36 | + self.assertNotIn("Cannot specify both EmbeddingsPathConfigurations and EmbeddingsTransformation", errors) |
| 37 | + self.assertEqual([], errors) |
| 38 | + |
| 39 | + def test_path_missing_chunking_options_is_rejected(self): |
| 40 | + # Mirrors C#: each path must carry ChunkingOptions. |
| 41 | + config = _config(embeddings_path_configurations=[EmbeddingPathConfiguration("Name", None)]) |
| 42 | + errors = _validate(config) |
| 43 | + self.assertIn("Path 'Name': ChunkingOptions must be provided.", errors) |
| 44 | + |
| 45 | + def test_path_invalid_chunking_options_is_rejected(self): |
| 46 | + # Each path's ChunkingOptions is validated with the path as the error source. |
| 47 | + config = _config( |
| 48 | + embeddings_path_configurations=[ |
| 49 | + EmbeddingPathConfiguration("Name", ChunkingOptions(ChunkingMethod.HTML_STRIP, 0, 0)) |
| 50 | + ] |
| 51 | + ) |
| 52 | + errors = _validate(config) |
| 53 | + self.assertTrue( |
| 54 | + any("Name" in e and "MaxTokensPerChunk" in e for e in errors), |
| 55 | + f"expected a per-path MaxTokensPerChunk error, got: {errors}", |
| 56 | + ) |
| 57 | + |
| 58 | + def test_path_with_valid_chunking_options_passes(self): |
| 59 | + config = _config( |
| 60 | + embeddings_path_configurations=[ |
| 61 | + EmbeddingPathConfiguration("Name", ChunkingOptions(ChunkingMethod.HTML_STRIP, 100, 0)) |
| 62 | + ] |
| 63 | + ) |
| 64 | + self.assertEqual([], _validate(config)) |
| 65 | + |
| 66 | + |
| 67 | +if __name__ == "__main__": |
| 68 | + unittest.main() |
0 commit comments