summaryrefslogtreecommitdiffstats
path: root/searchlib
diff options
context:
space:
mode:
authorArne Juul <arnej@verizonmedia.com>2020-08-16 09:48:49 +0000
committerArne Juul <arnej@verizonmedia.com>2020-08-16 10:15:45 +0000
commit662f115159d6eb972b0c8618b902289db2e04400 (patch)
tree3828f6760120989ad480c344793946ddf6c479ab /searchlib
parent7dfff82ef775341d2784b7b91092f78553748333 (diff)
test new parsing
Diffstat (limited to 'searchlib')
-rw-r--r--searchlib/src/tests/common/location/geo_location_test.cpp278
1 files changed, 211 insertions, 67 deletions
diff --git a/searchlib/src/tests/common/location/geo_location_test.cpp b/searchlib/src/tests/common/location/geo_location_test.cpp
index 31b844d0fc8..0ff0f586258 100644
--- a/searchlib/src/tests/common/location/geo_location_test.cpp
+++ b/searchlib/src/tests/common/location/geo_location_test.cpp
@@ -4,6 +4,7 @@
#include <vespa/searchlib/common/geo_location.h>
#include <vespa/searchlib/common/geo_location_spec.h>
#include <vespa/searchlib/common/geo_location_parser.h>
+#include <vespa/searchlib/query/tree/location.h>
#include <vespa/vespalib/gtest/gtest.h>
using search::common::GeoLocation;
@@ -23,12 +24,30 @@ bool is_parseable(const char *str) {
return parser.parseOldFormat(str);
}
+bool is_parseable_new(const char *str, bool with_field = false) {
+ GeoLocationParser parser;
+ if (with_field) {
+ return parser.parseWithField(str);
+ }
+ return parser.parseNoField(str);
+}
+
GeoLocation parse(const char *str) {
GeoLocationParser parser;
EXPECT_TRUE(parser.parseOldFormat(str));
return parser.getGeoLocation();
}
+GeoLocation parse_new(const std::string &str, bool with_field = false) {
+ GeoLocationParser parser;
+ if (with_field) {
+ EXPECT_TRUE(parser.parseWithField(str));
+ } else {
+ EXPECT_TRUE(parser.parseNoField(str));
+ }
+ return parser.getGeoLocation();
+}
+
TEST(GeoLocationParserTest, malformed_bounding_boxes_are_not_parseable) {
EXPECT_TRUE(is_parseable("[2,10,20,30,40]"));
EXPECT_FALSE(is_parseable("[2,10,20,30,40][2,10,20,30,40]"));
@@ -40,6 +59,15 @@ TEST(GeoLocationParserTest, malformed_bounding_boxes_are_not_parseable) {
EXPECT_FALSE(is_parseable("[10,20,30,40]"));
}
+TEST(GeoLocationParserTest, new_bounding_box_formats) {
+ EXPECT_TRUE(is_parseable_new("{b:{x:[10,30],y:[20,40]}}"));
+ EXPECT_TRUE(is_parseable_new("{b:{}}"));
+ EXPECT_TRUE(is_parseable_new("{b:[]}"));
+ EXPECT_TRUE(is_parseable_new("{b:10,b:20}"));
+ EXPECT_TRUE(is_parseable_new("{b:[10, 20, 30, 40]}"));
+ EXPECT_FALSE(is_parseable_new("{b:{x:[10,30],y:[20,40]}"));
+}
+
TEST(GeoLocationParserTest, malformed_circles_are_not_parseable) {
EXPECT_TRUE(is_parseable("(2,10,20,5,0,0,0)"));
EXPECT_FALSE(is_parseable("(2,10,20,5,0,0,0)(2,10,20,5,0,0,0)"));
@@ -52,94 +80,147 @@ TEST(GeoLocationParserTest, malformed_circles_are_not_parseable) {
EXPECT_FALSE(is_parseable("(10,20,5)"));
}
+TEST(GeoLocationParserTest, new_circle_formats) {
+ EXPECT_TRUE(is_parseable_new("{p:{x:10,y:20}}"));
+ EXPECT_TRUE(is_parseable_new("{p:{x:10,y:20},r:5}"));
+ EXPECT_TRUE(is_parseable_new("{p:{x:10, y:10}, r:5}"));
+ EXPECT_TRUE(is_parseable_new("{'p':{y:20,x:10},'r':5}"));
+ EXPECT_TRUE(is_parseable_new("{\n \"p\": { \"x\": 10, \"y\": 20},\n \"r\": 5\n}"));
+ // json demands colon:
+ EXPECT_FALSE(is_parseable_new("{p:{x:10,y:10},r=5}"));
+ // missing y -> 0 default:
+ EXPECT_TRUE(is_parseable_new("{p:{x:10},r:5}"));
+ // unused extra fields are ignored:
+ EXPECT_TRUE(is_parseable_new("{p:{x:10,y:10,z:10},r:5,c:1,d:17}"));
+}
+
TEST(GeoLocationParserTest, bounding_boxes_can_be_parsed) {
- auto loc = parse("[2,10,20,30,40]");
- EXPECT_EQ(false, loc.has_point);
- EXPECT_EQ(true, loc.bounding_box.active());
- EXPECT_EQ(0u, loc.x_aspect.multiplier);
- EXPECT_EQ(0, loc.point.x);
- EXPECT_EQ(0, loc.point.y);
- EXPECT_EQ(std::numeric_limits<uint32_t>::max(), loc.radius);
- EXPECT_EQ(10, loc.bounding_box.x.low);
- EXPECT_EQ(20, loc.bounding_box.y.low);
- EXPECT_EQ(30, loc.bounding_box.x.high);
- EXPECT_EQ(40, loc.bounding_box.y.high);
+ for (const auto & loc : {
+ parse("[2,10,20,30,40]"),
+ parse_new("{b:{x:[10,30],y:[20,40]}}")
+ }) {
+ EXPECT_EQ(false, loc.has_point);
+ EXPECT_EQ(true, loc.bounding_box.active());
+ EXPECT_EQ(0u, loc.x_aspect.multiplier);
+ EXPECT_EQ(0, loc.point.x);
+ EXPECT_EQ(0, loc.point.y);
+ EXPECT_EQ(std::numeric_limits<uint32_t>::max(), loc.radius);
+ EXPECT_EQ(10, loc.bounding_box.x.low);
+ EXPECT_EQ(20, loc.bounding_box.y.low);
+ EXPECT_EQ(30, loc.bounding_box.x.high);
+ EXPECT_EQ(40, loc.bounding_box.y.high);
+ }
}
TEST(GeoLocationParserTest, circles_can_be_parsed) {
- auto loc = parse("(2,10,20,5,0,0,0)");
- EXPECT_EQ(true, loc.has_point);
- EXPECT_EQ(true, loc.bounding_box.active());
- EXPECT_EQ(0u, loc.x_aspect.multiplier);
- EXPECT_EQ(10, loc.point.x);
- EXPECT_EQ(20, loc.point.y);
- EXPECT_EQ(5u, loc.radius);
- EXPECT_EQ(5, loc.bounding_box.x.low);
- EXPECT_EQ(15, loc.bounding_box.y.low);
- EXPECT_EQ(15, loc.bounding_box.x.high);
- EXPECT_EQ(25, loc.bounding_box.y.high);
+ for (const auto & loc : {
+ parse("(2,10,20,5,0,0,0)"),
+ parse_new("{p:{x:10,y:20},r:5}")
+ }) {
+ EXPECT_EQ(true, loc.has_point);
+ EXPECT_EQ(true, loc.bounding_box.active());
+ EXPECT_EQ(0u, loc.x_aspect.multiplier);
+ EXPECT_EQ(10, loc.point.x);
+ EXPECT_EQ(20, loc.point.y);
+ EXPECT_EQ(5u, loc.radius);
+ EXPECT_EQ(5, loc.bounding_box.x.low);
+ EXPECT_EQ(15, loc.bounding_box.y.low);
+ EXPECT_EQ(15, loc.bounding_box.x.high);
+ EXPECT_EQ(25, loc.bounding_box.y.high);
+ }
}
TEST(GeoLocationParserTest, circles_can_have_aspect_ratio) {
- auto loc = parse("(2,10,20,5,0,0,0,2147483648)");
- EXPECT_EQ(true, loc.has_point);
- EXPECT_EQ(true, loc.bounding_box.active());
- EXPECT_EQ(2147483648u, loc.x_aspect.multiplier);
- EXPECT_EQ(10, loc.point.x);
- EXPECT_EQ(20, loc.point.y);
- EXPECT_EQ(5u, loc.radius);
- EXPECT_EQ(-1, loc.bounding_box.x.low);
- EXPECT_EQ(15, loc.bounding_box.y.low);
- EXPECT_EQ(21, loc.bounding_box.x.high);
- EXPECT_EQ(25, loc.bounding_box.y.high);
+ for (const auto & loc : {
+ parse("(2,10,20,5,0,0,0,2147483648)"),
+ parse_new("{p:{x:10,y:20},r:5,a:2147483648}")
+ }) {
+ EXPECT_EQ(true, loc.has_point);
+ EXPECT_EQ(true, loc.bounding_box.active());
+ EXPECT_EQ(2147483648u, loc.x_aspect.multiplier);
+ EXPECT_EQ(10, loc.point.x);
+ EXPECT_EQ(20, loc.point.y);
+ EXPECT_EQ(5u, loc.radius);
+ EXPECT_EQ(-1, loc.bounding_box.x.low);
+ EXPECT_EQ(15, loc.bounding_box.y.low);
+ EXPECT_EQ(21, loc.bounding_box.x.high);
+ EXPECT_EQ(25, loc.bounding_box.y.high);
+ }
+ auto loc2 = parse_new("{p:{x:10,y:10},a:3123456789}");
+ EXPECT_EQ(3123456789, loc2.x_aspect.multiplier);
}
TEST(GeoLocationParserTest, bounding_box_can_be_specified_after_circle) {
- auto loc = parse("(2,10,20,5,0,0,0)[2,10,20,30,40]");
- EXPECT_EQ(true, loc.has_point);
- EXPECT_EQ(true, loc.bounding_box.active());
- EXPECT_EQ(0u, loc.x_aspect.multiplier);
- EXPECT_EQ(10, loc.point.x);
- EXPECT_EQ(20, loc.point.y);
- EXPECT_EQ(5u, loc.radius);
- EXPECT_EQ(10, loc.bounding_box.x.low);
- EXPECT_EQ(20, loc.bounding_box.y.low);
- EXPECT_EQ(15, loc.bounding_box.x.high);
- EXPECT_EQ(25, loc.bounding_box.y.high);
+ for (const auto & loc : {
+ parse("(2,10,20,5,0,0,0)[2,10,20,30,40]"),
+ parse_new("{p:{x:10,y:20},r:5,b:{x:[10,30],y:[20,40]}}")
+ }) {
+ EXPECT_EQ(true, loc.has_point);
+ EXPECT_EQ(true, loc.bounding_box.active());
+ EXPECT_EQ(0u, loc.x_aspect.multiplier);
+ EXPECT_EQ(10, loc.point.x);
+ EXPECT_EQ(20, loc.point.y);
+ EXPECT_EQ(5u, loc.radius);
+ EXPECT_EQ(10, loc.bounding_box.x.low);
+ EXPECT_EQ(20, loc.bounding_box.y.low);
+ EXPECT_EQ(15, loc.bounding_box.x.high);
+ EXPECT_EQ(25, loc.bounding_box.y.high);
+ }
}
TEST(GeoLocationParserTest, circles_can_be_specified_after_bounding_box) {
- auto loc = parse("[2,10,20,30,40](2,10,20,5,0,0,0)");
+ for (const auto & loc : {
+ parse("[2,10,20,30,40](2,10,20,5,0,0,0)"),
+ parse_new("{b:{x:[10,30],y:[20,40]},p:{x:10,y:20},r:5}")
+ }) {
+ EXPECT_EQ(true, loc.has_point);
+ EXPECT_EQ(true, loc.bounding_box.active());
+ EXPECT_EQ(0u, loc.x_aspect.multiplier);
+ EXPECT_EQ(10, loc.point.x);
+ EXPECT_EQ(20, loc.point.y);
+ EXPECT_EQ(5u, loc.radius);
+ EXPECT_EQ(10, loc.bounding_box.x.low);
+ EXPECT_EQ(20, loc.bounding_box.y.low);
+ EXPECT_EQ(15, loc.bounding_box.x.high);
+ EXPECT_EQ(25, loc.bounding_box.y.high);
+ }
+ const auto &loc = parse_new("{a:12345,b:{x:[8,10],y:[8,10]},p:{x:10,y:10},r:3}");
EXPECT_EQ(true, loc.has_point);
- EXPECT_EQ(true, loc.bounding_box.active());
- EXPECT_EQ(0u, loc.x_aspect.multiplier);
EXPECT_EQ(10, loc.point.x);
- EXPECT_EQ(20, loc.point.y);
- EXPECT_EQ(5u, loc.radius);
- EXPECT_EQ(10, loc.bounding_box.x.low);
- EXPECT_EQ(20, loc.bounding_box.y.low);
- EXPECT_EQ(15, loc.bounding_box.x.high);
- EXPECT_EQ(25, loc.bounding_box.y.high);
+ EXPECT_EQ(10, loc.point.y);
+ EXPECT_EQ(12345u, loc.x_aspect.multiplier);
}
TEST(GeoLocationParserTest, santa_search_gives_non_wrapped_bounding_box) {
- auto loc = parse("(2,122163600,89998536,290112,4,2000,0,109704)");
- EXPECT_GE(loc.bounding_box.x.high, loc.bounding_box.x.low);
- EXPECT_GE(loc.bounding_box.y.high, loc.bounding_box.y.low);
+ for (const auto & loc : {
+ parse("(2,122163600,89998536,290112,4,2000,0,109704)"),
+ parse_new("{p:{x:122163600,y:89998536},r:290112,a:109704}")
+ }) {
+ EXPECT_GE(loc.bounding_box.x.high, loc.bounding_box.x.low);
+ EXPECT_GE(loc.bounding_box.y.high, loc.bounding_box.y.low);
+ }
}
TEST(GeoLocationParserTest, near_boundary_search_gives_non_wrapped_bounding_box) {
- auto loc1 = parse("(2,2000000000,2000000000,3000000000,0,1,0)");
- EXPECT_GE(loc1.bounding_box.x.high, loc1.bounding_box.x.low);
- EXPECT_GE(loc1.bounding_box.y.high, loc1.bounding_box.y.low);
- EXPECT_EQ(std::numeric_limits<int32_t>::max(), loc1.bounding_box.y.high);
- EXPECT_EQ(std::numeric_limits<int32_t>::max(), loc1.bounding_box.y.high);
-
- auto loc2 = parse("(2,-2000000000,-2000000000,3000000000,0,1,0)");
- EXPECT_GE(loc2.bounding_box.x.high, loc2.bounding_box.x.low);
- EXPECT_GE(loc2.bounding_box.y.high, loc2.bounding_box.y.low);
- EXPECT_EQ(std::numeric_limits<int32_t>::min(), loc2.bounding_box.x.low);
- EXPECT_EQ(std::numeric_limits<int32_t>::min(), loc2.bounding_box.y.low);
+ for (const auto & loc1 : {
+ parse("(2,2000000000,2000000000,3000000000,0,1,0)"),
+ parse_new("{p:{x:2000000000,y:2000000000},r:3000000000}")
+ }) {
+ EXPECT_GE(loc1.bounding_box.x.high, loc1.bounding_box.x.low);
+ EXPECT_GE(loc1.bounding_box.y.high, loc1.bounding_box.y.low);
+ EXPECT_EQ(std::numeric_limits<int32_t>::max(), loc1.bounding_box.y.high);
+ EXPECT_EQ(std::numeric_limits<int32_t>::max(), loc1.bounding_box.y.high);
+ }
+
+ for (const auto & loc2 : {
+ parse("(2,-2000000000,-2000000000,3000000000,0,1,0)"),
+ parse_new("{p:{x:-2000000000,y:-2000000000},r:3000000000}")
+ }) {
+ EXPECT_GE(loc2.bounding_box.x.high, loc2.bounding_box.x.low);
+ EXPECT_GE(loc2.bounding_box.y.high, loc2.bounding_box.y.low);
+ EXPECT_EQ(std::numeric_limits<int32_t>::min(), loc2.bounding_box.x.low);
+ EXPECT_EQ(std::numeric_limits<int32_t>::min(), loc2.bounding_box.y.low);
+ }
}
void check_box(const GeoLocation &location, Box expected)
@@ -391,4 +472,67 @@ TEST(GeoLocationTest, box_point_radius_and_aspect) {
EXPECT_EQ(location.bounding_box.y.high, 700);
}
+TEST(GeoLocationParserTest, can_parse_what_query_tree_produces) {
+ search::query::Point point_1{-17, 42};
+ uint32_t distance = 12345;
+ uint32_t aspect_ratio = 67890;
+ search::query::Rectangle rectangle_1(-1, -2, 3, 4);
+
+ search::query::Location loc_1(point_1);
+ std::string str_1 = loc_1.getJsonFormatString();
+ auto result_1 = parse_new(str_1);
+
+ EXPECT_EQ(true, result_1.has_point);
+ EXPECT_EQ(false, result_1.has_radius());
+ EXPECT_EQ(false, result_1.x_aspect.active());
+ EXPECT_EQ(false, result_1.bounding_box.active());
+ EXPECT_EQ(-17, result_1.point.x);
+ EXPECT_EQ(42, result_1.point.y);
+
+ search::query::Location loc_1b(point_1, distance, aspect_ratio);
+ std::string str_1b = loc_1b.getJsonFormatString();
+ auto result_1b = parse_new(str_1b);
+
+ EXPECT_EQ(true, result_1b.has_point);
+ EXPECT_EQ(true, result_1b.has_radius());
+ EXPECT_EQ(true, result_1b.x_aspect.active());
+ EXPECT_EQ(true, result_1b.bounding_box.active());
+ EXPECT_EQ(-17, result_1b.point.x);
+ EXPECT_EQ(42, result_1b.point.y);
+ EXPECT_EQ(distance, result_1b.radius);
+ EXPECT_EQ(aspect_ratio, result_1b.x_aspect.multiplier);
+ EXPECT_EQ(42-distance, result_1b.bounding_box.y.low);
+ EXPECT_EQ(42+distance, result_1b.bounding_box.y.high);
+
+ search::query::Location loc_2(rectangle_1);
+ std::string str_2 = loc_2.getJsonFormatString();
+ auto result_2 = parse_new(str_2);
+
+ EXPECT_EQ(false, result_2.has_point);
+ EXPECT_EQ(false, result_2.has_radius());
+ EXPECT_EQ(false, result_2.x_aspect.active());
+ EXPECT_EQ(true, result_2.bounding_box.active());
+ EXPECT_EQ(-1, result_2.bounding_box.x.low);
+ EXPECT_EQ(-2, result_2.bounding_box.y.low);
+ EXPECT_EQ(3, result_2.bounding_box.x.high);
+ EXPECT_EQ(4, result_2.bounding_box.y.high);
+
+ search::query::Location loc_3(rectangle_1, point_1, distance, aspect_ratio);
+ std::string str_3 = loc_3.getJsonFormatString();
+ auto result_3 = parse_new(str_3);
+
+ EXPECT_EQ(true, result_3.has_point);
+ EXPECT_EQ(true, result_3.has_radius());
+ EXPECT_EQ(true, result_3.x_aspect.active());
+ EXPECT_EQ(true, result_3.bounding_box.active());
+ EXPECT_EQ(-17, result_3.point.x);
+ EXPECT_EQ(42, result_3.point.y);
+ EXPECT_EQ(distance, result_3.radius);
+ EXPECT_EQ(aspect_ratio, result_3.x_aspect.multiplier);
+ EXPECT_EQ(-1, result_3.bounding_box.x.low);
+ EXPECT_EQ(-2, result_3.bounding_box.y.low);
+ EXPECT_EQ(3, result_3.bounding_box.x.high);
+ EXPECT_EQ(4, result_3.bounding_box.y.high);
+}
+
GTEST_MAIN_RUN_ALL_TESTS()