use super::*;
use linkrs_core::value::geography::{Geography, GeographyValue, LineStringValue, PolygonValue};
use linkrs_core::value::NullType;
use linkrs_core::Value;
#[test]
fn test_st_point() {
let func = GeographyFunction::StPoint;
let result = func
.execute(&[Value::Float(116.4074), Value::Float(39.9042)])
.expect("Implementation should not fail");
assert!(matches!(result, Value::Geography(_)));
}
#[test]
fn test_st_isvalid() {
let func = GeographyFunction::StIsValid;
let geo = Geography::Point(GeographyValue::new(39.9042, 116.4074));
let result = func
.execute(&[Value::Geography(geo)])
.expect("Implementation should not fail");
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_st_distance() {
let func = GeographyFunction::StDistance;
let geo1 = Geography::Point(GeographyValue::new(39.9042, 116.4074));
let geo2 = Geography::Point(GeographyValue::new(31.2304, 121.4737));
let result = func
.execute(&[Value::Geography(geo1), Value::Geography(geo2)])
.expect("Implementation should not fail");
assert!(matches!(result, Value::Float(_)));
}
#[test]
fn test_null_handling() {
let func = GeographyFunction::StIsValid;
let result = func
.execute(&[Value::Null(NullType::Null)])
.expect("Implementation should not fail");
assert_eq!(result, Value::Null(NullType::Null));
}
#[test]
fn test_st_linestring() {
let wkt = "LINESTRING(116.4 39.9, 121.5 31.2)";
let result = execute_st_geogfromtext(&[Value::string(wkt)]).unwrap();
assert!(matches!(result, Value::Geography(Geography::LineString(_))));
}
#[test]
fn test_st_polygon() {
let wkt = "POLYGON((116.0 40.0, 117.0 40.0, 117.0 39.0, 116.0 39.0, 116.0 40.0))";
let result = execute_st_geogfromtext(&[Value::string(wkt)]).unwrap();
assert!(matches!(result, Value::Geography(Geography::Polygon(_))));
}
#[test]
fn test_st_length() {
let ls = LineStringValue::new(vec![
GeographyValue::new(39.9, 116.4),
GeographyValue::new(31.2, 121.5),
]);
let result = execute_st_length(&[Value::Geography(Geography::LineString(ls))]).unwrap();
assert!(matches!(result, Value::Double(d) if d > 1000.0));
}
#[test]
fn test_st_contains() {
let polygon = PolygonValue::new(
LineStringValue::new(vec![
GeographyValue::new(40.0, 116.0),
GeographyValue::new(40.0, 117.0),
GeographyValue::new(39.0, 117.0),
GeographyValue::new(39.0, 116.0),
GeographyValue::new(40.0, 116.0),
]),
vec![],
);
let point_inside = Geography::Point(GeographyValue::new(39.5, 116.5));
let point_outside = Geography::Point(GeographyValue::new(50.0, 120.0));
let result_inside = execute_st_contains(&[
Value::Geography(Geography::Polygon(polygon.clone())),
Value::Geography(point_inside),
])
.unwrap();
assert_eq!(result_inside, Value::Bool(true));
let result_outside = execute_st_contains(&[
Value::Geography(Geography::Polygon(polygon)),
Value::Geography(point_outside),
])
.unwrap();
assert_eq!(result_outside, Value::Bool(false));
}
#[test]
fn test_st_geometrytype() {
let point = Geography::Point(GeographyValue::new(39.9, 116.4));
let result = execute_st_geometrytype(&[Value::Geography(point)]).unwrap();
assert_eq!(result, Value::string("Point"));
let ls = Geography::LineString(LineStringValue::new(vec![
GeographyValue::new(39.9, 116.4),
GeographyValue::new(31.2, 121.5),
]));
let result = execute_st_geometrytype(&[Value::Geography(ls)]).unwrap();
assert_eq!(result, Value::string("LineString"));
}
#[test]
fn test_st_buffer() {
let point = Geography::Point(GeographyValue::new(39.9, 116.4));
let result = execute_st_buffer(&[Value::Geography(point), Value::Double(10.0)]).unwrap();
assert!(matches!(result, Value::Geography(Geography::Polygon(_))));
}
#[test]
fn test_st_boundary() {
let ls = LineStringValue::new(vec![
GeographyValue::new(39.9, 116.4),
GeographyValue::new(31.2, 121.5),
]);
let result = execute_st_boundary(&[Value::Geography(Geography::LineString(ls))]).unwrap();
assert!(matches!(result, Value::Geography(Geography::MultiPoint(_))));
let polygon = PolygonValue::new(
LineStringValue::new(vec![
GeographyValue::new(40.0, 116.0),
GeographyValue::new(40.0, 117.0),
GeographyValue::new(39.0, 117.0),
GeographyValue::new(39.0, 116.0),
GeographyValue::new(40.0, 116.0),
]),
vec![],
);
let result = execute_st_boundary(&[Value::Geography(Geography::Polygon(polygon))]).unwrap();
assert!(matches!(result, Value::Geography(Geography::LineString(_))));
}
#[test]
fn test_st_crosses() {
let polygon = PolygonValue::new(
LineStringValue::new(vec![
GeographyValue::new(40.0, 116.0),
GeographyValue::new(40.0, 117.0),
GeographyValue::new(39.0, 117.0),
GeographyValue::new(39.0, 116.0),
GeographyValue::new(40.0, 116.0),
]),
vec![],
);
let ls = LineStringValue::new(vec![
GeographyValue::new(39.5, 116.5),
GeographyValue::new(40.5, 116.5),
]);
let result = execute_st_crosses(&[
Value::Geography(Geography::LineString(ls)),
Value::Geography(Geography::Polygon(polygon)),
])
.unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_st_touches() {
let point = Geography::Point(GeographyValue::new(40.0, 116.0));
let ls = LineStringValue::new(vec![
GeographyValue::new(40.0, 116.0),
GeographyValue::new(40.0, 117.0),
]);
let result = execute_st_touches(&[
Value::Geography(point),
Value::Geography(Geography::LineString(ls)),
])
.unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_st_overlaps() {
let p1 = PolygonValue::new(
LineStringValue::new(vec![
GeographyValue::new(40.0, 116.0),
GeographyValue::new(40.0, 117.0),
GeographyValue::new(39.0, 117.0),
GeographyValue::new(39.0, 116.0),
GeographyValue::new(40.0, 116.0),
]),
vec![],
);
let p2 = PolygonValue::new(
LineStringValue::new(vec![
GeographyValue::new(39.5, 116.5),
GeographyValue::new(39.5, 117.5),
GeographyValue::new(38.5, 117.5),
GeographyValue::new(38.5, 116.5),
GeographyValue::new(39.5, 116.5),
]),
vec![],
);
let result = execute_st_overlaps(&[
Value::Geography(Geography::Polygon(p1)),
Value::Geography(Geography::Polygon(p2)),
])
.unwrap();
assert_eq!(result, Value::Bool(true));
}
#[test]
fn test_st_equals() {
let p1 = Geography::Point(GeographyValue::new(39.9, 116.4));
let p2 = Geography::Point(GeographyValue::new(39.9, 116.4));
let result = execute_st_equals(&[Value::Geography(p1), Value::Geography(p2)]).unwrap();
assert_eq!(result, Value::Bool(true));
let p3 = Geography::Point(GeographyValue::new(31.2, 121.5));
let result = execute_st_equals(&[
Value::Geography(Geography::Point(GeographyValue::new(39.9, 116.4))),
Value::Geography(p3),
])
.unwrap();
assert_eq!(result, Value::Bool(false));
}
#[test]
fn test_st_asgeojson() {
let point = Geography::Point(GeographyValue::new(39.9, 116.4));
let result = execute_st_asgeojson(&[Value::Geography(point)]).unwrap();
if let Value::String(json) = result {
assert!(json.contains("\"type\":\"Point\""));
assert!(json.contains("\"coordinates\""));
} else {
panic!("Expected String value");
}
}
#[test]
fn test_st_geomfromgeojson() {
let json = r#"{"type":"Point","coordinates":[116.4,39.9]}"#;
let result = execute_st_geomfromgeojson(&[Value::string(json)]).unwrap();
assert!(matches!(result, Value::Geography(Geography::Point(_))));
}
#[test]
fn test_geojson_roundtrip() {
let point = Geography::Point(GeographyValue::new(39.9, 116.4));
let json = execute_st_asgeojson(&[Value::Geography(point.clone())]).unwrap();
let parsed = execute_st_geomfromgeojson(&[json]).unwrap();
assert_eq!(Value::Geography(point), parsed);
}