planetiler/planetiler-core/src/test/java/com/onthegomap/planetiler/expression/MultiExpressionTest.java

705 wiersze
31 KiB
Java

package com.onthegomap.planetiler.expression;
import static com.onthegomap.planetiler.TestUtils.newLineString;
import static com.onthegomap.planetiler.TestUtils.newPoint;
import static com.onthegomap.planetiler.TestUtils.rectangle;
import static com.onthegomap.planetiler.expression.Expression.*;
import static com.onthegomap.planetiler.expression.ExpressionTestUtil.featureWithTags;
import static com.onthegomap.planetiler.expression.MultiExpression.entry;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import com.onthegomap.planetiler.expression.MultiExpression.Index;
import com.onthegomap.planetiler.reader.SimpleFeature;
import com.onthegomap.planetiler.reader.SourceFeature;
import com.onthegomap.planetiler.reader.WithTags;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import org.junit.jupiter.api.Test;
class MultiExpressionTest {
@Test
void testEmpty() {
var index = MultiExpression.<String>of(List.of()).index();
assertSameElements(List.of(), index.getMatches(featureWithTags()));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "value")));
}
@Test
void testSingleElement() {
var index = MultiExpression.of(List.of(
entry("a", matchAny("key", "value"))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testSingleElementBooleanTrue() {
var index = MultiExpression.of(List.of(
entry("a", matchAnyTyped("key", WithTags::getBoolean, true))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "true")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "yes")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "true", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "true", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "false")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testSingleElementBooleanFalse() {
var index = MultiExpression.of(List.of(
entry("a", matchAnyTyped("key", WithTags::getBoolean, false))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "false")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "no")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "0")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "false", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "false", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "true")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testSingleElementLong() {
var index = MultiExpression.of(List.of(
entry("a", matchAnyTyped("key", WithTags::getLong, 42))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "42")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "42", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "42", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "99")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testSingleElementDirection() {
var index = MultiExpression.of(List.of(
entry("a", matchAnyTyped("key", WithTags::getDirection, 1))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "yes")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "1", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "1", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "99")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testBlankStringTreatedAsNotMatch() {
var index = MultiExpression.of(List.of(
entry("a", matchAny("key", "value", ""))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags()));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("otherkey", "othervalue")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "value", "key3", "value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "no")));
}
@Test
void testSingleMatchField() {
var index = MultiExpression.of(List.of(
entry("a", matchField("key"))
)).index();
matchFieldCheck(index);
}
@Test
void testDoubleInverseMatchField() {
var index = MultiExpression.of(List.of(
entry("a", not(not(matchField("key"))))
)).index();
matchFieldCheck(index);
}
private void matchFieldCheck(Index<String> index) {
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value2", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", null)));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testInverseMatchField() {
var index = MultiExpression.of(List.of(
entry("a", not(matchField("key")))
)).index();
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", null)));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "value2", "otherkey", "othervalue")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "value", "key3", "value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "no")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags()));
}
@Test
void testStaticBooleanMatch() {
var index = MultiExpression.of(List.of(entry("t", TRUE))).index();
assertTrue(index.matches(featureWithTags("key", "value")));
index = MultiExpression.of(List.of(entry("f", FALSE))).index();
assertFalse(index.matches(featureWithTags("key", "value")));
index = MultiExpression.of(List.of(
entry("a", matchField("key")),
entry("t", TRUE),
entry("f", FALSE)
)).index();
assertSameElements(List.of("a", "t"), index.getMatches(featureWithTags("key", "value")));
index = MultiExpression.of(List.of(
entry("a", matchField("key")),
entry("t1", TRUE),
entry("t2", TRUE),
entry("t3", TRUE),
entry("f1", FALSE),
entry("f2", FALSE),
entry("f3", FALSE)
)).index();
assertSameElements(List.of("a", "t1", "t2", "t3"), index.getMatches(featureWithTags("key", "value")));
index = MultiExpression.of(List.of(
entry("t3", TRUE),
entry("t2", TRUE),
entry("t1", TRUE),
entry("a", matchField("key"))
)).index();
assertSameElements(List.of("t3", "t2", "t1", "a"), index.getMatches(featureWithTags("key", "value")));
}
@Test
void testWildcard() {
var index = MultiExpression.of(List.of(
entry("a", matchAny("key", "%value%"))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "1value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "1value1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "1value1", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testStartsWith() {
var index = MultiExpression.of(List.of(
entry("a", matchAny("key", "value%"))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "1value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "1value1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "1value1", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testEndsWith() {
var index = MultiExpression.of(List.of(
entry("a", matchAny("key", "%value"))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "value1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "1value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "1value1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "1value1", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testMultipleMatches() {
var feature = featureWithTags("a", "b", "c", "d");
var index = MultiExpression.of(List.of(
entry("a", matchAny("a", "b")),
entry("b", matchAny("c", "d"))
)).index();
var index2 = MultiExpression.of(List.of(
entry("b", matchAny("c", "d")),
entry("a", matchAny("a", "b"))
)).index();
assertSameElements(List.of("a", "b"), index.getMatches(feature));
assertSameElements(List.of("b", "a"), index2.getMatches(feature));
assertEquals("a", index.getOrElse(feature, "miss"));
assertEquals("b", index2.getOrElse(feature, "miss"));
}
@Test
void testMultipleWildcardsMixedWithExacts() {
var index = MultiExpression.of(List.of(
entry("a", matchAny("key", "%value%", "other"))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "1value1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "other")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "1value1", "otherkey", "othervalue")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "other", "otherkey", "othervalue")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value", "key3", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testAnd() {
var index = MultiExpression.of(List.of(
entry("a", and(
matchAny("key1", "val1"),
matchAny("key2", "val2")
))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val2", "key3", "val3")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testAndConstant() {
var index = MultiExpression.of(List.of(
entry("a", and(
Expression.TRUE,
matchAny("key1", "val1")
))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
index = MultiExpression.of(List.of(
entry("a", and(
Expression.FALSE,
matchAny("key1", "val1")
))
)).index();
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testOr() {
var index = MultiExpression.of(List.of(
entry("a", or(
matchAny("key1", "val1"),
matchAny("key2", "val2")
))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val2", "key3", "val3")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "no", "key2", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testMapResult() {
var index = MultiExpression.of(List.of(
entry("a", matchField("key"))
)).mapResults(result -> result.toUpperCase(Locale.ROOT)).index();
assertSameElements(List.of("A"), index.getMatches(featureWithTags("key", "value")));
}
@Test
void testFilterResults() {
var index = MultiExpression.of(List.of(
entry("a", matchField("key")),
entry("b", matchField("key"))
)).filterResults(result -> !result.equals("b")).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "value")));
}
@Test
void testOrConstant() {
var index = MultiExpression.of(List.of(
entry("a", or(
Expression.TRUE,
matchAny("key1", "val1")
))
)).indexAndWarn();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags()));
index = MultiExpression.of(List.of(
entry("a", or(
Expression.FALSE,
matchAny("key1", "val1")
))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testNot() {
var index = MultiExpression.of(List.of(
entry("a", and(
matchAny("key1", "val1"),
not(
matchAny("key2", "val2")
)
))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val3")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key3", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testNor() {
var index = MultiExpression.of(List.of(
entry("a", not(or(
matchAny("key1", "val1"),
matchAny("key2", "val2")
)))
)).index();
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "val2", "key3", "val3")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags()));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "no", "key2", "no")));
}
@Test
void testNand() {
var index = MultiExpression.of(List.of(
entry("a", not(and(
matchAny("key1", "val1"),
matchAny("key2", "val2")
)))
)).index();
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "val2", "key3", "val3")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags()));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
}
@Test
void testXor() {
var index = MultiExpression.of(List.of(
entry("a",
or(
and(
not(matchAny("key1", "val1")),
matchAny("key2", "val2")
),
and(
matchAny("key1", "val1"),
not(matchAny("key2", "val2"))
))
)
)).index();
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "val2", "key3", "val3")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "no", "key2", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testXnor() {
var index = MultiExpression.of(List.of(
entry("a",
or(
and(
not(matchAny("key1", "val1")),
not(matchAny("key2", "val2"))
),
and(
matchAny("key1", "val1"),
matchAny("key2", "val2")
))
)
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1", "key2", "val2", "key3", "val3")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "no", "key2", "val2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1", "key2", "no")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "no", "key2", "no")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags()));
}
@Test
void testMatchesMultiple() {
var index = MultiExpression.of(List.of(
entry("a", or(
matchAny("key1", "val1"),
matchAny("key2", "val2")
)),
entry("b", or(
matchAny("key2", "val2"),
matchAny("key3", "val3")
))
)).index();
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "val1")));
assertSameElements(List.of("a", "b"), index.getMatches(featureWithTags("key2", "val2")));
assertSameElements(List.of("b"), index.getMatches(featureWithTags("key3", "val3")));
assertSameElements(List.of("a", "b"), index.getMatches(featureWithTags("key2", "val2", "key3", "val3")));
assertSameElements(List.of("a", "b"), index.getMatches(featureWithTags("key1", "val1", "key3", "val3")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
}
@Test
void testTracksMatchingKey() {
var index = MultiExpression.of(List.of(
entry("a", or(
matchAny("key1", "val1"),
matchAny("key2", "val2")
)),
entry("b", or(
matchAny("key2", "val2"),
matchAny("key3", "val3")
))
)).index();
assertSameElements(List.of(new MultiExpression.Match<>(
"a", List.of("key1"), 1
)), index.getMatchesWithTriggers(featureWithTags("key1", "val1")));
assertSameElements(List.of(new MultiExpression.Match<>(
"a", List.of("key2"), 1
), new MultiExpression.Match<>(
"b", List.of("key2"), 2
)), index.getMatchesWithTriggers(featureWithTags("key2", "val2")));
assertSameElements(List.of(new MultiExpression.Match<>(
"b", List.of("key3"), 2
)), index.getMatchesWithTriggers(featureWithTags("key3", "val3")));
}
@Test
void testTracksMatchingKeyFromCorrectPath() {
var index = MultiExpression.of(List.of(
entry("a", or(
and(
matchAny("key3", "val3"),
matchAny("key2", "val2")
),
and(
matchAny("key1", "val1"),
matchAny("key3", "val3")
)
))
)).index();
assertSameElements(List.of(new MultiExpression.Match<>(
"a", List.of("key1", "key3"), 1
)), index.getMatchesWithTriggers(featureWithTags("key1", "val1", "key3", "val3")));
}
@Test
void testMatchDifferentTypes() {
Expression polygonExpression = and(matchType("polygon"), matchField("field"));
Expression linestringExpression = and(matchType("linestring"), matchField("field"));
Expression pointExpression = and(matchType("point"), matchField("field"));
Expression otherExpression = matchField("field");
Map<String, Object> map = Map.of("field", "value");
SourceFeature point = SimpleFeature.create(newPoint(0, 0), map);
SourceFeature linestring = SimpleFeature.create(newLineString(0, 0, 1, 1), map);
SourceFeature polygon = SimpleFeature.create(rectangle(0, 1), map);
WithTags other = WithTags.from(Map.of("field", "value"));
var index = MultiExpression.of(List.of(
entry("polygon", polygonExpression),
entry("linestring", linestringExpression),
entry("point", pointExpression),
entry("other", otherExpression)
)).index();
assertTrue(pointExpression.evaluate(point, new ArrayList<>()));
assertTrue(linestringExpression.evaluate(linestring, new ArrayList<>()));
assertTrue(polygonExpression.evaluate(polygon, new ArrayList<>()));
assertTrue(otherExpression.evaluate(other, new ArrayList<>()));
assertEquals("point", index.getOrElse(point, null));
assertEquals("linestring", index.getOrElse(linestring, null));
assertEquals("polygon", index.getOrElse(polygon, null));
assertEquals("other", index.getOrElse(other, null));
}
@Test
void testMatchMissing() {
// Test logic: match if either key1 or key2 is missing
var index1 = MultiExpression.of(List.of(
entry("a", or(
matchAny("key1", ""),
matchAny("key2", "")
))
)).index();
var index2 = MultiExpression.of(List.of(
entry("a", not(and(
matchField("key1"),
matchField("key2")
)))
)).index();
List.of(index1, index2).forEach(index -> {
assertSameElements(List.of("a"), index.getMatches(featureWithTags()));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "value1")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key2", "value2")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key1", "value1", "key2", "value2")));
});
}
@Test
void testMatchNotMissing() {
//Test logic: match if key1 is present (not missing)
var index1 = MultiExpression.of(List.of(
entry("a", matchField("key1"))
)).index();
var index2 = MultiExpression.of(List.of(
entry("a", not(
matchAny("key1", "")
))
)).index();
List.of(index1, index2).forEach(index -> {
assertSameElements(List.of(), index.getMatches(featureWithTags()));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "value1")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key2", "value2")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key1", "value1", "key2", "value2")));
});
}
@Test
void testCustomExpression() {
Expression dontEvaluate = new Expression() {
@Override
public boolean evaluate(WithTags input, List<String> matchKeys) {
throw new AssertionError("should not evaluate");
}
@Override
public String generateJavaCode() {
return null;
}
};
Expression matchAbc = new Expression() {
@Override
public boolean evaluate(WithTags input, List<String> matchKeys) {
return input.hasTag("abc");
}
@Override
public String generateJavaCode() {
return null;
}
};
var index = MultiExpression.of(List.of(
entry("a", matchAbc),
entry("b", and(matchField("def"), dontEvaluate)),
entry("c", or(matchField("abc"), matchAbc))
)).index();
assertSameElements(List.of(), index.getMatches(featureWithTags()));
assertSameElements(List.of(), index.getMatches(featureWithTags("a", "1")));
assertSameElements(List.of("a", "c"), index.getMatches(featureWithTags("abc", "123")));
var bad = featureWithTags("def", "123");
assertThrows(AssertionError.class, () -> index.getMatches(bad));
}
@Test
void testAndOrMatch() {
var expr = and(
or(
matchAny("key", "val")
),
TRUE
);
var index = MultiExpression.of(List.of(entry("a", expr))).index();
//Ensure MultiExpression and regular Expression work the same
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "val")));
assertSameElements(List.of("a"), index.getMatches(featureWithTags("key", "val", "otherkey", "otherval")));
assertSameElements(List.of(), index.getMatches(featureWithTags("otherkey", "otherval")));
assertSameElements(List.of(), index.getMatches(featureWithTags("key", "otherval")));
assertSameElements(List.of(), index.getMatches(featureWithTags()));
var list = new ArrayList<String>();
assertTrue(expr.evaluate(featureWithTags("key", "val"), list));
assertTrue(expr.evaluate(featureWithTags("key", "val", "otherkey", "otherval"), list));
assertFalse(expr.evaluate(featureWithTags("otherkey", "otherval"), list));
assertFalse(expr.evaluate(featureWithTags("key", "otherval"), list));
assertFalse(expr.evaluate(featureWithTags(), list));
expr.simplify();
//Ensure Expression works the same after a simplify
assertTrue(expr.evaluate(featureWithTags("key", "val"), list));
assertTrue(expr.evaluate(featureWithTags("key", "val", "otherkey", "otherval"), list));
assertFalse(expr.evaluate(featureWithTags("otherkey", "otherval"), list));
assertFalse(expr.evaluate(featureWithTags("key", "otherval"), list));
assertFalse(expr.evaluate(featureWithTags(), list));
}
private static <T> void assertSameElements(List<T> a, List<T> b) {
assertEquals(
a.stream().sorted(Comparator.comparing(Object::toString)).toList(),
b.stream().sorted(Comparator.comparing(Object::toString)).toList()
);
}
}