extern crate assert_cli; // extern crate geoq; use assert_cli::Assert; #[test] fn it_gets_basic_debug_info_for_inputs() { let input = "12,34 12 34 9q5 {\"type\":\"Point\",\"coordinates\":[125.6, 10.1]} LINESTRING (30 10, 10 30, 40 40) "; let output = r#"LatLon: 12,34 LatLon: 12 34 Geohash: 9q5 GeoJSON Geometry: {"type":"Point","coordinates":[125.6, 10.1]} WKT: LINESTRING(30 10,10 30,40 40) "#; Assert::main_binary() .with_args(&["read"]) .stdin(input) .stdout() .contains(output) .unwrap(); } #[test] fn exits_on_invalid_input() { Assert::main_binary() .with_args(&["read"]) .stdin("pizza") .stderr() .contains("Application error: InvalidInput(\"Unable to parse single-line input: pizza\")") .fails() .unwrap(); } #[test] fn invalid_wkt() { let input = "Polygon ((30 10, 10 30, 40 40, 30 10)"; Assert::main_binary() .with_args(&["read"]) .stdin(input) .stderr() .is("Application error: InvalidWkt") .fails() .unwrap(); } #[test] fn it_outputs_wkt() { let input = r#"12,34 12 34 9q5 LINESTRING (30 10, 10 30, 40 40) {"type":"Point","coordinates":[125.6, 10.1]} {"type":"Feature","properties":{"a": "b"},"geometry":{"type":"Point","coordinates":[125.6, 10.1]}} {"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[34.0,12.0]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[78.0,56.0]}}]} "#; let output = r#"POINT(34 12) POINT(34 12) POLYGON((-119.53125 33.75,-118.125 33.75,-118.125 35.15625,-119.53125 35.15625,-119.53125 33.75)) LINESTRING(30 10,10 30,40 40) POINT(125.6 10.1) POINT(125.6 10.1) POINT(34 12) POINT(78 56) "#; Assert::main_binary() .with_args(&["wkt"]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] fn outputs_geojson_geoms() { let input = r#"12,34 12 34 9q5 LINESTRING (30 10, 10 30, 40 40) {"type":"Point","coordinates":[125.6, 10.1]} {"type":"Feature","properties":{"a": "b"},"geometry":{"type":"Point","coordinates":[125.6, 10.1]}} {"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[34.0,12.0]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[78.0,56.0]}}]} "#; let output = r#"{"coordinates":[34.0,12.0],"type":"Point"} {"coordinates":[34.0,12.0],"type":"Point"} {"coordinates":[[[-119.53125,33.75],[-118.125,33.75],[-118.125,35.15625],[-119.53125,35.15625],[-119.53125,33.75]]],"type":"Polygon"} {"coordinates":[[30.0,10.0],[10.0,30.0],[40.0,40.0]],"type":"LineString"} {"coordinates":[125.6,10.1],"type":"Point"} {"coordinates":[125.6,10.1],"type":"Point"} {"coordinates":[34.0,12.0],"type":"Point"} {"coordinates":[78.0,56.0],"type":"Point"} "#; Assert::main_binary() .with_args(&["gj", "geom"]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] fn outputs_geojson_features() { let input = r#"12,34 12 34 9q5 LINESTRING (30 10, 10 30, 40 40) {"type":"Point","coordinates":[125.6, 10.1]} {"type":"Feature","properties":{"a": "b"},"geometry":{"type":"Point","coordinates":[125.6, 10.1]}} {"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[34.0,12.0]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[78.0,56.0]}}]} "#; let output = r#"{"geometry":{"coordinates":[34.0,12.0],"type":"Point"},"properties":{},"type":"Feature"} {"geometry":{"coordinates":[34.0,12.0],"type":"Point"},"properties":{},"type":"Feature"} {"geometry":{"coordinates":[[[-119.53125,33.75],[-118.125,33.75],[-118.125,35.15625],[-119.53125,35.15625],[-119.53125,33.75]]],"type":"Polygon"},"properties":{},"type":"Feature"} {"geometry":{"coordinates":[[30.0,10.0],[10.0,30.0],[40.0,40.0]],"type":"LineString"},"properties":{},"type":"Feature"} {"geometry":{"coordinates":[125.6,10.1],"type":"Point"},"properties":{},"type":"Feature"} {"geometry":{"coordinates":[125.6,10.1],"type":"Point"},"properties":{"a":"b"},"type":"Feature"} {"geometry":{"coordinates":[34.0,12.0],"type":"Point"},"properties":{},"type":"Feature"} {"geometry":{"coordinates":[78.0,56.0],"type":"Point"},"properties":{},"type":"Feature"} "#; Assert::main_binary() .with_args(&["gj", "f"]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] fn outputs_geojson_featurecollection() { let input = r#"12,34 12 34 9q5 LINESTRING (30 10, 10 30, 40 40) {"type":"Point","coordinates":[125.6, 10.1]} {"type":"Feature","properties":{"a": "b"},"geometry":{"type":"Point","coordinates":[125.6, 10.1]}} "#; let output = r#"{"features":[{"geometry":{"coordinates":[34.0,12.0],"type":"Point"},"properties":{},"type":"Feature"},{"geometry":{"coordinates":[34.0,12.0],"type":"Point"},"properties":{},"type":"Feature"},{"geometry":{"coordinates":[[[-119.53125,33.75],[-118.125,33.75],[-118.125,35.15625],[-119.53125,35.15625],[-119.53125,33.75]]],"type":"Polygon"},"properties":{},"type":"Feature"},{"geometry":{"coordinates":[[30.0,10.0],[10.0,30.0],[40.0,40.0]],"type":"LineString"},"properties":{},"type":"Feature"},{"geometry":{"coordinates":[125.6,10.1],"type":"Point"},"properties":{},"type":"Feature"},{"geometry":{"coordinates":[125.6,10.1],"type":"Point"},"properties":{"a":"b"},"type":"Feature"}],"type":"FeatureCollection"}"#; Assert::main_binary() .with_args(&["gj", "fc"]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] fn outputs_geohash_for_point() { let input = r#"12,34 12 34 34,-118 "#; let output = r#"sf0hm8w sf0hm8w 9qh16ve "#; Assert::main_binary() .with_args(&["gh", "point", "7"]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] fn geohash_not_allowed_for_non_point() { let input = "LINESTRING (30 10, 10 30, 40 40)\n"; Assert::main_binary() .with_args(&["gh", "point", "7"]) .stdin(input) .fails() .unwrap(); } #[test] fn geohash_fails_for_missing_or_invalid_level() { let input = "LINESTRING (30 10, 10 30, 40 40)\n"; Assert::main_binary() .with_args(&["gh", "point", "pizza"]) .stdin(input) .fails() .unwrap(); Assert::main_binary() .with_args(&["gh", "point"]) .stdin(input) .fails() .unwrap(); } #[test] fn geohash_children() { let input = "9q5\n"; let output = r#"9q50 9q51 9q52 9q53 9q54 9q55 9q56 9q57 9q58 9q59 9q5b 9q5c 9q5d 9q5e 9q5f 9q5g 9q5h 9q5j 9q5k 9q5m 9q5n 9q5p 9q5q 9q5r 9q5s 9q5t 9q5u 9q5v 9q5w 9q5x 9q5y 9q5z "#; Assert::main_binary() .with_args(&["gh", "children"]) .stdin(input) .stdout() .is(output) .unwrap(); Assert::main_binary() .with_args(&["gh", "children"]) .stdin("LINESTRING (30 10, 10 30, 40 40)\n") .fails() .unwrap(); } #[test] fn geohash_neighbors() { let input = "9g3m\n"; let output_with = r#"9g3m 9g3q 9g3w 9g3t 9g3s 9g3k 9g3h 9g3j 9g3n "#; let output_without = r#"9g3q 9g3w 9g3t 9g3s 9g3k 9g3h 9g3j 9g3n "#; Assert::main_binary() .with_args(&["gh", "neighbors"]) .stdin(input) .stdout() .is(output_with) .unwrap(); Assert::main_binary() .with_args(&["gh", "neighbors", "-e"]) .stdin(input) .stdout() .is(output_without) .unwrap(); Assert::main_binary() .with_args(&["gh", "neighbors"]) .stdin("LINESTRING (30 10, 10 30, 40 40)\n") .fails() .unwrap(); } #[test] fn geohash_covering() { let input = r#"12,34 12 34 9q5 LINESTRING (30 10, 10 30, 40 40) {"type":"Point","coordinates":[125.6, 10.1]} {"type":"Feature","properties":{"a": "b"},"geometry":{"type":"Point","coordinates":[125.6, 10.1]}} {"type":"FeatureCollection","features":[{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[34.0,12.0]}},{"type":"Feature","properties":{},"geometry":{"type":"Point","coordinates":[78.0,56.0]}}]} "#; let output_with = r#"12,34 sf0 12 34 sf0 9q5 9qk 9qh 9q7 9q6 9q5 9q4 9mu 9mg 9mf LINESTRING(30 10,10 30,40 40) szh sz5 syg syf syc syb sy8 swx sww swt swm swk sw7 sw6 sw4 sw1 sw0 sqp smz smy smv smu sms sme smd sm9 sm3 sm2 sm0 skh skd skc skb sk9 sk7 sk6 sk5 sjr sjp se0 sdh sdd sdc sdb sd9 sd7 sd6 sd5 s9v s9u s7w s7v s7u s7t s7r s7q s7p {"type":"Point","coordinates":[125.6, 10.1]} wcc {"type":"Feature","properties":{"a": "b"},"geometry":{"type":"Point","coordinates":[125.6, 10.1]}} wcc {"geometry":{"coordinates":[34.0,12.0],"type":"Point"},"properties":{},"type":"Feature"} sf0 {"geometry":{"coordinates":[78.0,56.0],"type":"Point"},"properties":{},"type":"Feature"} v9z "#; let output_without = r#"sf0 sf0 9qk 9qh 9q7 9q6 9q5 9q4 9mu 9mg 9mf szh sz5 syg syf syc syb sy8 swx sww swt swm swk sw7 sw6 sw4 sw1 sw0 sqp smz smy smv smu sms sme smd sm9 sm3 sm2 sm0 skh skd skc skb sk9 sk7 sk6 sk5 sjr sjp se0 sdh sdd sdc sdb sd9 sd7 sd6 sd5 s9v s9u s7w s7v s7u s7t s7r s7q s7p wcc wcc sf0 v9z "#; Assert::main_binary() .with_args(&["gh", "covering", "3"]) .stdin(input) .stdout() .is(output_without) .unwrap(); Assert::main_binary() .with_args(&["gh", "covering", "3", "-o"]) .stdin(input) .stdout() .is(output_with) .unwrap(); } #[test] fn gh_covering_errors() { let input = "LINESTRING (30 10, 10 30, 40 40)\n"; Assert::main_binary() .with_args(&["gh", "covering", "pizza"]) .stdin(input) .fails() .unwrap(); Assert::main_binary() .with_args(&["gh", "covering"]) .stdin(input) .fails() .unwrap(); } #[test] fn gj_geom_edge_case() { let input = r#"{"coordinates":[[[-87.97874531338036,34.92420945798039],[-87.9785957342853,34.92418491767909],[-87.97857664070615,34.9242631544226],[-87.97872621980122,34.92428769470051],[-87.97874531338036,34.92420945798039]]],"type":"Polygon"} "#; Assert::main_binary() .with_args(&["gj", "geom"]) .stdin(input) .stdout() .is(input) .unwrap(); } #[test] fn filter_intersects() { let input = r#"34.2277,-118.2623 {"type":"Polygon","coordinates":[[[-117.87231445312499,34.77997173591062],[-117.69653320312499,34.77997173591062],[-117.69653320312499,34.90170042871546],[-117.87231445312499,34.90170042871546],[-117.87231445312499,34.77997173591062]]]} {"type":"Polygon","coordinates":[[[-118.27880859375001,34.522398580663314],[-117.89154052734375,34.522398580663314],[-117.89154052734375,34.649025753526985],[-118.27880859375001,34.649025753526985],[-118.27880859375001,34.522398580663314]]]} "#; let output = r#"34.2277,-118.2623 {"type":"Polygon","coordinates":[[[-118.27880859375001,34.522398580663314],[-117.89154052734375,34.522398580663314],[-117.89154052734375,34.649025753526985],[-118.27880859375001,34.649025753526985],[-118.27880859375001,34.522398580663314]]]} "#; Assert::main_binary() .with_args(&["filter", "intersects", "9q5"]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] fn filter_intersects_query_file() { let input = r#"34.2277,-118.2623 {"type":"Polygon","coordinates":[[[-117.87231445312499,34.77997173591062],[-117.69653320312499,34.77997173591062],[-117.69653320312499,34.90170042871546],[-117.87231445312499,34.90170042871546],[-117.87231445312499,34.77997173591062]]]} {"type":"Polygon","coordinates":[[[-118.27880859375001,34.522398580663314],[-117.89154052734375,34.522398580663314],[-117.89154052734375,34.649025753526985],[-118.27880859375001,34.649025753526985],[-118.27880859375001,34.522398580663314]]]} "#; let output = r#"34.2277,-118.2623 {"type":"Polygon","coordinates":[[[-118.27880859375001,34.522398580663314],[-117.89154052734375,34.522398580663314],[-117.89154052734375,34.649025753526985],[-118.27880859375001,34.649025753526985],[-118.27880859375001,34.522398580663314]]]} "#; Assert::main_binary() .with_args(&[ "filter", "intersects", "--query-file", "./tests/resources/query_file.txt", ]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] fn filter_intersects_linestring() { let input = r#"{"type":"Feature","properties":{},"geometry":{"type":"LineString","coordinates":[[-18.6328125,32.54681317351514],[33.75,-2.460181181020993]]}} "#; let filter = r#"{"type":"Feature","properties":{},"geometry":{"type":"LineString","coordinates":[[21.4453125,30.44867367928756],[-1.40625,-9.79567758282973]]}}"#; Assert::main_binary() .with_args(&["filter", "intersects", filter]) .stdin(input) .stdout() .is(input) .unwrap(); } #[test] #[ignore] fn reading_geojson_feature_without_properties() { let input = r#"{"type":"Feature","geometry":{"type":"Point","coordinates":[125.6, 10.1]}} {"type":"Feature","properties":null,"geometry":{"type":"Point","coordinates":[125.6, 10.1]}} "#; Assert::main_binary() .with_args(&["wkt"]) .stdin(input) .stderr() .is("") .unwrap(); } #[test] fn json_munge() { let input = r#"{"latitude": 34.3, "longitude": -118.2, "name": "Horace", "pizza": "pie"} {"lat": 34.3, "lon": -118.2, "name": "Horace", "pizza": "pie"} {"latitude": 34.3, "lng": -118.2, "name": "Horace", "pizza": "pie"} {"name": "Horace", "pizza": "pie", "wkt":"POINT(-118.3991 33.9924)"} "#; let output = r#"{"geometry":{"coordinates":[-118.2,34.3],"type":"Point"},"properties":{"name":"Horace","pizza":"pie"},"type":"Feature"} {"geometry":{"coordinates":[-118.2,34.3],"type":"Point"},"properties":{"name":"Horace","pizza":"pie"},"type":"Feature"} {"geometry":{"coordinates":[-118.2,34.3],"type":"Point"},"properties":{"name":"Horace","pizza":"pie"},"type":"Feature"} {"geometry":{"coordinates":[-118.3991,33.9924],"type":"Point"},"properties":{"name":"Horace","pizza":"pie"},"type":"Feature"} "#; Assert::main_binary() .with_args(&["json", "munge"]) .stdin(input) .stdout() .is(output) .unwrap(); Assert::main_binary() .with_args(&["json", "munge"]) .stdin("pizza") .fails() .unwrap(); Assert::main_binary() .with_args(&["json", "point"]) .stdin("[\"not-json-object\"]") .fails() .unwrap(); Assert::main_binary() .with_args(&["json", "point"]) .stdin("{\"no-lat-lon\": \"hi\"}") .fails() .unwrap(); } #[test] fn filter_contains() { let input = r#"{"type": "LineString", "coordinates": [[-44.2529296875, 25.3241665257384], [-42.802734375, 25.502784548755354]]} {"type": "LineString", "coordinates": [[-45.41748046875, 24.186847428521244], [-45, 22.004174972902003]]} {"type": "Point", "coordinates": [-47.4609375, 21.453068633086783]} "#; let output = r#"{"type": "LineString", "coordinates": [[-45.41748046875, 24.186847428521244], [-45, 22.004174972902003]]} {"type": "Point", "coordinates": [-47.4609375, 21.453068633086783]} "#; let filter = r#"{"type": "Polygon", "coordinates": [[[-50.185546875, 18.22935133838668], [-43.681640625, 18.22935133838668], [-43.681640625, 26.03704188651584], [-50.185546875, 26.03704188651584], [-50.185546875, 18.22935133838668]]]}"#; Assert::main_binary() .with_args(&["filter", "contains", filter]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] fn filter_contains_file() { let input = r#"{"type": "LineString", "coordinates": [[-44.2529296875, 25.3241665257384], [-42.802734375, 25.502784548755354]]} {"type": "LineString", "coordinates": [[-45.41748046875, 24.186847428521244], [-45, 22.004174972902003]]} {"type": "Point", "coordinates": [-47.4609375, 21.453068633086783]} "#; let output = r#"{"type": "LineString", "coordinates": [[-45.41748046875, 24.186847428521244], [-45, 22.004174972902003]]} {"type": "Point", "coordinates": [-47.4609375, 21.453068633086783]} "#; Assert::main_binary() .with_args(&[ "filter", "contains", "--query-file", "./tests/resources/query_file.txt", ]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] #[ignore] fn json_geom() { let input = r#"{"latitude": 34.3, "longitude": -118.2, "name": "Horace", "pizza": "pie"} {"lat": 34.3, "lon": -118.2, "name": "Horace", "pizza": "pie"} {"latitude": 34.3, "lng": -118.2, "name": "Horace", "pizza": "pie"} "#; let output = r#"{"geometry":{"coordinates":[-118.2,34.3],"type":"Point"},"properties":{"latitude":34.3,"longitude":-118.2,"name":"Horace","pizza":"pie"},"type":"Feature"} {"geometry":{"coordinates":[-118.2,34.3],"type":"Point"},"properties":{"lat":34.3,"lon":-118.2,"name":"Horace","pizza":"pie"},"type":"Feature"} {"geometry":{"coordinates":[-118.2,34.3],"type":"Point"},"properties":{"latitude":34.3,"lng":-118.2,"name":"Horace","pizza":"pie"},"type":"Feature"} "#; Assert::main_binary() .with_args(&["json", "point"]) .stdin(input) .stdout() .is(output) .unwrap(); Assert::main_binary() .with_args(&["json", "point"]) .stdin("pizza") .fails() .unwrap(); Assert::main_binary() .with_args(&["json", "point"]) .stdin("[\"not-json-object\"]") .fails() .unwrap(); Assert::main_binary() .with_args(&["json", "point"]) .stdin("{\"no-lat-lon\": \"hi\"}") .fails() .unwrap(); } #[test] fn centroid() { let input = r#"{"type": "LineString", "coordinates": [[-44.2529296875, 25.3241665257384], [-42.802734375, 25.502784548755354]]} {"type": "Point", "coordinates": [-47.4609375, 21.453068633086783]} Polygon ((30 10, 10 30, 40 40, 30 10)) "#; let output = r#"{"coordinates":[-43.52783203125,25.413475537246875],"type":"Point"} {"coordinates":[-47.4609375,21.453068633086783],"type":"Point"} {"coordinates":[26.66666666666667,26.66666666666667],"type":"Point"} "#; Assert::main_binary() .with_args(&["centroid"]) .stdin(input) .stdout() .is(output) .unwrap(); } #[test] fn gh_roots() { let output = r#"0 1 2 3 4 5 6 7 8 9 b c d e f g h j k m n p q r s t u v w x y z "#; Assert::main_binary() .with_args(&["gh", "roots"]) .stdout() .is(output) .unwrap(); }