Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -160,4 +160,134 @@ void testBuildWithAllProperties() {
assertThat(document.getMetadata()).isEqualTo(metadata);
}

@Test
void testWithWhitespaceOnlyId() {
assertThatThrownBy(() -> this.builder.text("text").id(" ").build())
.isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("id cannot be null or empty");
}

@Test
void testWithEmptyText() {
Document document = this.builder.text("").build();
assertThat(document.getText()).isEqualTo("");
}

@Test
void testOverwritingText() {
Document document = this.builder.text("initial text").text("final text").build();
assertThat(document.getText()).isEqualTo("final text");
}

@Test
void testMultipleMetadataKeyValueCalls() {
Document document = this.builder.text("text")
.metadata("key1", "value1")
.metadata("key2", "value2")
.metadata("key3", 123)
.build();

assertThat(document.getMetadata()).hasSize(3)
.containsEntry("key1", "value1")
.containsEntry("key2", "value2")
.containsEntry("key3", 123);
}

@Test
void testMetadataMapOverridesKeyValue() {
Map<String, Object> metadata = new HashMap<>();
metadata.put("newKey", "newValue");

Document document = this.builder.text("text").metadata("oldKey", "oldValue").metadata(metadata).build();

assertThat(document.getMetadata()).hasSize(1).containsEntry("newKey", "newValue").doesNotContainKey("oldKey");
}

@Test
void testKeyValueMetadataAfterMap() {
Map<String, Object> metadata = new HashMap<>();
metadata.put("mapKey", "mapValue");

Document document = this.builder.text("text")
.metadata(metadata)
.metadata("additionalKey", "additionalValue")
.build();

assertThat(document.getMetadata()).hasSize(2)
.containsEntry("mapKey", "mapValue")
.containsEntry("additionalKey", "additionalValue");
}

@Test
void testWithEmptyMetadataMap() {
Map<String, Object> emptyMetadata = new HashMap<>();

Document document = this.builder.text("text").metadata(emptyMetadata).build();

assertThat(document.getMetadata()).isEmpty();
}

@Test
void testOverwritingMetadataWithSameKey() {
Document document = this.builder.text("text")
.metadata("key", "firstValue")
.metadata("key", "secondValue")
.build();

assertThat(document.getMetadata()).hasSize(1).containsEntry("key", "secondValue");
}

@Test
void testWithNullMedia() {
Document document = this.builder.text("text").media(null).build();
assertThat(document.getMedia()).isNull();
}

@Test
void testIdOverridesIdGenerator() {
IdGenerator generator = contents -> "generated-id";

Document document = this.builder.text("text").idGenerator(generator).id("explicit-id").build();

assertThat(document.getId()).isEqualTo("explicit-id");
}

@Test
void testComplexMetadataTypes() {
Map<String, Object> nestedMap = new HashMap<>();
nestedMap.put("nested", "value");

Document document = this.builder.text("text")
.metadata("string", "text")
.metadata("integer", 42)
.metadata("double", 3.14)
.metadata("boolean", true)
.metadata("map", nestedMap)
.build();

assertThat(document.getMetadata()).hasSize(5)
.containsEntry("string", "text")
.containsEntry("integer", 42)
.containsEntry("double", 3.14)
.containsEntry("boolean", true)
.containsEntry("map", nestedMap);
}

@Test
void testBuilderReuse() {
// First document
Document doc1 = this.builder.text("first").id("id1").metadata("key", "value1").build();

// Reuse builder for second document
Document doc2 = this.builder.text("second").id("id2").metadata("key", "value2").build();

assertThat(doc1.getId()).isEqualTo("id1");
assertThat(doc1.getText()).isEqualTo("first");
assertThat(doc1.getMetadata()).containsEntry("key", "value1");

assertThat(doc2.getId()).isEqualTo("id2");
assertThat(doc2.getText()).isEqualTo("second");
assertThat(doc2.getMetadata()).containsEntry("key", "value2");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -96,4 +96,101 @@ void renderWithMissingVariableShouldThrow() {
}
}

@Test
void builderWithWhitespaceOnlyTemplateShouldThrow() {
assertThatThrownBy(() -> PromptTemplate.builder().template(" ")).isInstanceOf(IllegalArgumentException.class)
.hasMessageContaining("template cannot be null or empty");
}

@Test
void builderWithEmptyVariablesMapShouldWork() {
Map<String, Object> emptyVariables = new HashMap<>();
PromptTemplate promptTemplate = PromptTemplate.builder()
.template("Status: active")
.variables(emptyVariables)
.build();

assertThat(promptTemplate.render()).isEqualTo("Status: active");
}

@Test
void builderNullVariableValueShouldWork() {
Map<String, Object> variables = new HashMap<>();
variables.put("value", null);

PromptTemplate promptTemplate = PromptTemplate.builder()
.template("Result: {value}")
.variables(variables)
.build();

// Should handle null values gracefully
String result = promptTemplate.render();
assertThat(result).contains("Result:").contains(":");
}

@Test
void builderWithMultipleMissingVariablesShouldThrow() {
PromptTemplate promptTemplate = PromptTemplate.builder()
.template("Processing {item} with {type} at {level}")
.build();

try {
promptTemplate.render();
Assertions.fail("Expected IllegalStateException was not thrown.");
}
catch (IllegalStateException e) {
assertThat(e.getMessage()).contains("Not all variables were replaced in the template");
assertThat(e.getMessage()).contains("item", "type", "level");
}
}

@Test
void builderWithPartialVariablesShouldThrow() {
Map<String, Object> variables = new HashMap<>();
variables.put("item", "data");
// Missing 'type' variable

PromptTemplate promptTemplate = PromptTemplate.builder()
.template("Processing {item} with {type}")
.variables(variables)
.build();

try {
promptTemplate.render();
Assertions.fail("Expected IllegalStateException was not thrown.");
}
catch (IllegalStateException e) {
assertThat(e.getMessage()).contains("Missing variable names are: [type]");
}
}

@Test
void builderWithCompleteVariablesShouldRender() {
Map<String, Object> variables = new HashMap<>();
variables.put("item", "data");
variables.put("count", 42);

PromptTemplate promptTemplate = PromptTemplate.builder()
.template("Processing {item} with count {count}")
.variables(variables)
.build();

String result = promptTemplate.render();
assertThat(result).isEqualTo("Processing data with count 42");
}

@Test
void builderWithEmptyStringVariableShouldWork() {
Map<String, Object> variables = new HashMap<>();
variables.put("name", "");

PromptTemplate promptTemplate = PromptTemplate.builder()
.template("Hello '{name}'!")
.variables(variables)
.build();

String result = promptTemplate.render();
assertThat(result).isEqualTo("Hello ''!");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,11 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.AND;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.EQ;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.GT;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.GTE;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.IN;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.LT;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.LTE;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.NE;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.NIN;
import static org.springframework.ai.vectorstore.filter.Filter.ExpressionType.NOT;
Expand Down Expand Up @@ -121,4 +124,122 @@ public void tesNot() {
null));
}

@Test
public void testLessThanOperators() {
// value < 1
var ltExp = this.b.lt("value", 1).build();
assertThat(ltExp).isEqualTo(new Expression(LT, new Key("value"), new Value(1)));

// value <= 1
var lteExp = this.b.lte("value", 1).build();
assertThat(lteExp).isEqualTo(new Expression(LTE, new Key("value"), new Value(1)));
}

@Test
public void testGreaterThanOperators() {
// value > 1
var gtExp = this.b.gt("value", 1).build();
assertThat(gtExp).isEqualTo(new Expression(GT, new Key("value"), new Value(1)));

// value >= 10
var gteExp = this.b.gte("value", 10).build();
assertThat(gteExp).isEqualTo(new Expression(GTE, new Key("value"), new Value(10)));
}

@Test
public void testNullValues() {
// status == null
var exp = this.b.eq("status", null).build();
assertThat(exp).isEqualTo(new Expression(EQ, new Key("status"), new Value(null)));
}

@Test
public void testEmptyInClause() {
// category IN []
var exp = this.b.in("category").build();
assertThat(exp).isEqualTo(new Expression(IN, new Key("category"), new Value(List.of())));
}

@Test
public void testSingleValueInClause() {
// type IN ["basic"]
var exp = this.b.in("type", "basic").build();
assertThat(exp).isEqualTo(new Expression(IN, new Key("type"), new Value(List.of("basic"))));
}

@Test
public void testComplexNestedGroups() {
// ((level >= 1 AND level <= 5) OR status == "special") AND (region IN ["north",
// "south"] OR enabled == true)
var exp = this.b.and(
this.b.or(this.b.group(this.b.and(this.b.gte("level", 1), this.b.lte("level", 5))),
this.b.eq("status", "special")),
this.b.group(this.b.or(this.b.in("region", "north", "south"), this.b.eq("enabled", true))))
.build();

Expression expected = new Expression(AND,
new Expression(OR,
new Group(new Expression(AND, new Expression(GTE, new Key("level"), new Value(1)),
new Expression(LTE, new Key("level"), new Value(5)))),
new Expression(EQ, new Key("status"), new Value("special"))),
new Group(
new Expression(OR, new Expression(IN, new Key("region"), new Value(List.of("north", "south"))),
new Expression(EQ, new Key("enabled"), new Value(true)))));

assertThat(exp).isEqualTo(expected);
}

@Test
public void testNotWithSimpleExpression() {
// NOT (active == true)
var exp = this.b.not(this.b.eq("active", true)).build();
assertThat(exp).isEqualTo(new Expression(NOT, new Expression(EQ, new Key("active"), new Value(true)), null));
}

@Test
public void testNotWithGroup() {
// NOT (level >= 3 AND region == "east")
var exp = this.b.not(this.b.group(this.b.and(this.b.gte("level", 3), this.b.eq("region", "east")))).build();

Expression expected = new Expression(NOT,
new Group(new Expression(AND, new Expression(GTE, new Key("level"), new Value(3)),
new Expression(EQ, new Key("region"), new Value("east")))),
null);

assertThat(exp).isEqualTo(expected);
}

@Test
public void testMultipleNotOperators() {
// NOT (NOT (active == true))
var exp = this.b.not(this.b.not(this.b.eq("active", true))).build();

Expression expected = new Expression(NOT,
new Expression(NOT, new Expression(EQ, new Key("active"), new Value(true)), null), null);

assertThat(exp).isEqualTo(expected);
}

@Test
public void testSpecialCharactersInKeys() {
// "item.name" == "test" AND "meta-data" != null
var exp = this.b.and(this.b.eq("item.name", "test"), this.b.ne("meta-data", null)).build();

Expression expected = new Expression(AND, new Expression(EQ, new Key("item.name"), new Value("test")),
new Expression(NE, new Key("meta-data"), new Value(null)));

assertThat(exp).isEqualTo(expected);
}

@Test
public void testEmptyStringValues() {
// description == "" OR label != ""
var exp = this.b.or(this.b.eq("description", ""), this.b.ne("label", "")).build();

Expression expected = new Expression(OR, new Expression(EQ, new Key("description"), new Value("")),
new Expression(NE, new Key("label"), new Value("")));

assertThat(exp).isEqualTo(expected);
}

}