Skip to content

Commit

Permalink
Tests for GeoJson parsers
Browse files Browse the repository at this point in the history
  • Loading branch information
2kai2kai2 committed Nov 9, 2023
1 parent 90bbf1d commit d80d1b9
Show file tree
Hide file tree
Showing 5 changed files with 302 additions and 141 deletions.
36 changes: 34 additions & 2 deletions apps/ios/GuideDogs.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -666,10 +666,12 @@
914BAAF32AD745E400CB2171 /* DestinationManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 914BAAF22AD745E400CB2171 /* DestinationManagerTest.swift */; };
914BAAFD2AD7483300CB2171 /* AudioEngineTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 914BAAFC2AD7483300CB2171 /* AudioEngineTest.swift */; };
915FF9F62ADE4BAF002B3690 /* AuthoredActivityContentTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 915FF9F42ADE3F91002B3690 /* AuthoredActivityContentTest.swift */; };
91745DD52AFB0E6C003EC104 /* GeoJsonGeometryTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91745DD42AFB0E6C003EC104 /* GeoJsonGeometryTest.swift */; };
91745DD62AFB0F32003EC104 /* GeometryUtilsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 914DEBDC2A3CE901007B161C /* GeometryUtilsTest.swift */; };
91745DD82AFC48E0003EC104 /* GeoJsonFeatureTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91745DD72AFC48E0003EC104 /* GeoJsonFeatureTest.swift */; };
91B6ADAA2AF19CB600FFE4E9 /* OSMServiceModelTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91B6ADA92AF19CB600FFE4E9 /* OSMServiceModelTest.swift */; };
91C82AAD2A5DCF040086D126 /* GeolocationManagerTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91C82AAC2A5DCF040086D126 /* GeolocationManagerTest.swift */; };
91C82ABE2A6B08500086D126 /* RouteGuidanceTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 91C82ABD2A6B08500086D126 /* RouteGuidanceTest.swift */; };
91DC0CF92A46134600244CC8 /* GeometryUtilsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 914DEBDC2A3CE901007B161C /* GeometryUtilsTest.swift */; };
B90C27D61EAF81D600007368 /* Sound.swift in Sources */ = {isa = PBXBuildFile; fileRef = B90C27D51EAF81D600007368 /* Sound.swift */; };
B918EE9825100FFF00A5354A /* CalloutRangeContext.swift in Sources */ = {isa = PBXBuildFile; fileRef = B918EE9725100FFF00A5354A /* CalloutRangeContext.swift */; };
B91D3F6427AB5546004159A8 /* UserAction.swift in Sources */ = {isa = PBXBuildFile; fileRef = B91D3F6327AB5546004159A8 /* UserAction.swift */; };
Expand Down Expand Up @@ -1585,6 +1587,8 @@
914DEBCD2A3CE6B9007B161C /* UnitTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
914DEBDC2A3CE901007B161C /* GeometryUtilsTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeometryUtilsTest.swift; sourceTree = "<group>"; };
915FF9F42ADE3F91002B3690 /* AuthoredActivityContentTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AuthoredActivityContentTest.swift; sourceTree = "<group>"; };
91745DD42AFB0E6C003EC104 /* GeoJsonGeometryTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeoJsonGeometryTest.swift; sourceTree = "<group>"; };
91745DD72AFC48E0003EC104 /* GeoJsonFeatureTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeoJsonFeatureTest.swift; sourceTree = "<group>"; };
91B6ADA92AF19CB600FFE4E9 /* OSMServiceModelTest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OSMServiceModelTest.swift; sourceTree = "<group>"; };
91C82AAC2A5DCF040086D126 /* GeolocationManagerTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = " GeolocationManagerTest.swift"; path = "UnitTests/Sensors/Geolocation/Geolocation Manager/ GeolocationManagerTest.swift"; sourceTree = SOURCE_ROOT; };
91C82ABD2A6B08500086D126 /* RouteGuidanceTest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = RouteGuidanceTest.swift; path = "UnitTests/Behaviors/Route Guidance/RouteGuidanceTest.swift"; sourceTree = SOURCE_ROOT; };
Expand Down Expand Up @@ -4347,6 +4351,31 @@
path = "Authored Activities";
sourceTree = "<group>";
};
91745DD12AFB0E6C003EC104 /* Models */ = {
isa = PBXGroup;
children = (
91745DD22AFB0E6C003EC104 /* JSON Parsing */,
);
path = Models;
sourceTree = "<group>";
};
91745DD22AFB0E6C003EC104 /* JSON Parsing */ = {
isa = PBXGroup;
children = (
91745DD32AFB0E6C003EC104 /* OSM */,
);
path = "JSON Parsing";
sourceTree = "<group>";
};
91745DD32AFB0E6C003EC104 /* OSM */ = {
isa = PBXGroup;
children = (
91745DD72AFC48E0003EC104 /* GeoJsonFeatureTest.swift */,
91745DD42AFB0E6C003EC104 /* GeoJsonGeometryTest.swift */,
);
path = OSM;
sourceTree = "<group>";
};
91C82AA62A4F56A70086D126 /* Sensors */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -4374,6 +4403,7 @@
91C82AB52A67182E0086D126 /* Data */ = {
isa = PBXGroup;
children = (
91745DD12AFB0E6C003EC104 /* Models */,
915FF9F32ADE3F91002B3690 /* Authored Activities */,
914BAAF12AD745E400CB2171 /* Destination Manager */,
914BAAED2AD745BC00CB2171 /* Services */,
Expand Down Expand Up @@ -5561,8 +5591,10 @@
914BAAF32AD745E400CB2171 /* DestinationManagerTest.swift in Sources */,
91C82ABE2A6B08500086D126 /* RouteGuidanceTest.swift in Sources */,
91C82AAD2A5DCF040086D126 /* GeolocationManagerTest.swift in Sources */,
91DC0CF92A46134600244CC8 /* GeometryUtilsTest.swift in Sources */,
91745DD82AFC48E0003EC104 /* GeoJsonFeatureTest.swift in Sources */,
91745DD52AFB0E6C003EC104 /* GeoJsonGeometryTest.swift in Sources */,
91B6ADAA2AF19CB600FFE4E9 /* OSMServiceModelTest.swift in Sources */,
91745DD62AFB0F32003EC104 /* GeometryUtilsTest.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
144 changes: 6 additions & 138 deletions apps/ios/UnitTests/App/Helpers/GeometryUtilsTest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,132 +12,6 @@ import CoreLocation

class GeometryUtilsTest: XCTestCase {

// TODO: `GeometryUtils::coordinates(geoJson:)` would be better if the `GeometryType` enum used associated values (coordinates), which would let us avoid the fact that it currently returns a vague `[Any]?` and instead just return a `GeometryType`. According to comments in `GeometryUtils`, the reason for this is compatibility with Objective-C. However, if we can move away from that, we could have much better code.

// GeoJSON strings taken/adapted from the GeoJSON spec, RFC-7946

/// normal test case for `GeometryUtils::coordinates(geoJson:)`
func testGeoJSONCoordinates_Point() throws {
/// `Point`-- coordinates are a `[Double]`
let point = GeometryUtils.coordinates(geoJson: """
{
"type": "Point",
"coordinates": [100.0, 0.0]
}
""")
XCTAssertEqual(point.type, GeometryType.point)
XCTAssertEqual(point.points as! [Double], [100.0, 0.0])
}

/// normal test case for `GeometryUtils::coordinates(geoJson:)`
func testGeoJSONCoordinates_LineString() throws {
/// `LineString`-- coordinates are a `[[Double]]`
let lineString = GeometryUtils.coordinates(geoJson: """
{
"type": "LineString",
"coordinates": [
[100.0, 0.0],
[101.0, 1.0]
]
}
""")
XCTAssertEqual(lineString.type, GeometryType.lineString)
XCTAssertEqual(lineString.points as! [[Double]], [[100.0, 0.0], [101.0, 1.0]])
}
/// normal test case for `GeometryUtils::coordinates(geoJson:)`
func testGeoJSONCoordinates_Polygon() throws {
/// `Polygon`-- coordinates are a `[[[Double]]]`
let poly = GeometryUtils.coordinates(geoJson: """
{
"type": "Polygon",
"coordinates": [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2],
[100.2, 0.8],
[100.8, 0.8]
]
]
}
""")
XCTAssertEqual(poly.type, GeometryType.polygon)
XCTAssertEqual(poly.points as! [[[Double]]], [
[
[100.0, 0.0],
[101.0, 0.0],
[101.0, 1.0],
[100.0, 1.0],
[100.0, 0.0]
],
[
[100.8, 0.8],
[100.8, 0.2],
[100.2, 0.2],
[100.2, 0.8],
[100.8, 0.8]
]
])
}

// Skipping type `MultiPoint` as equivalent
// Skipping type `MultiLineString` as equivalent
// Skipping type `MultiPolygon` as equivalent

func testGeoJSONCoordinates_invalidType() throws {
let a = GeometryUtils.coordinates(geoJson: """
{
"type": "a",
"coordinates": [100.0, 0.0]
}
""")
// TODO: apparently invalid types become GeometryType.multiPolygon - should it?
XCTAssertEqual(a.type, .multiPolygon)
XCTAssertEqual(a.points as! [Double], [100.0, 0.0])
}

/// edge case for `GeometryUtils::coordinates(geoJson:)` with empty input
/// which should result in `(nil, nil)`
func testGeoJSONCoordinates_emptystring() throws {
let emptyString = GeometryUtils.coordinates(geoJson: "")
XCTAssertNil(emptyString.type)
XCTAssertNil(emptyString.points)
}

/// edge cases for `GeometryUtils::coordinates(geoJson:)` with malformed json
/// which should result in `(nil, nil)`
func testGeoJSONCoordinates_malformed() throws {
let badKey = GeometryUtils.coordinates(geoJson: "{a: 1}");
XCTAssertNil(badKey.type)
XCTAssertNil(badKey.points)

let badValue = GeometryUtils.coordinates(geoJson: "{\"a\": asdf}")
XCTAssertNil(badValue.type)
XCTAssertNil(badValue.points)
}

/// edge cases for `GeometryUtils::coordinates(geoJson:)` with missing keys
/// which should result in one or both return fields being `nil`
func testGeoJSONCoordinates_missing() throws {
let noType = GeometryUtils.coordinates(geoJson: """
{"coordinates": [100.0, 0.0]}
""")
XCTAssertNil(noType.type)
XCTAssertEqual(noType.points as! [Double], [100.0, 0.0])

let noCoords = GeometryUtils.coordinates(geoJson: """
{"type": "Point"}
""")
XCTAssertEqual(noCoords.type, GeometryType.point)
XCTAssertNil(noCoords.points)
}
// TODO: test `geometryContainsLocation`
func testExample() throws {
XCTAssert(Soundscape.GeometryUtils.geometryContainsLocation(location: CLLocationCoordinate2D.init(latitude: 1, longitude: 1), coordinates: [CLLocationCoordinate2D.init(latitude: 1, longitude: 1), CLLocationCoordinate2D.init(latitude: 3, longitude: 3)]))
Expand Down Expand Up @@ -334,25 +208,21 @@ class GeometryUtilsTest: XCTestCase {
for lon in [0.0, 5.0, 10.0, 15.0, 20.0] {
let on_path = CLLocationCoordinate2DMake(0, lon)
let on_path_closest = GeometryUtils.closestEdge(from: on_path, on: path)
XCTAssertNotNil(on_path_closest)
XCTAssertEqual(on_path_closest!.coordinate, on_path)
XCTAssertEqual(on_path_closest, on_path)

let parallel = CLLocationCoordinate2DMake(10, lon)
let parallel_closest = GeometryUtils.closestEdge(from: parallel, on: path)
XCTAssertNotNil(parallel_closest)
XCTAssertEqual(parallel_closest!.coordinate, on_path)
XCTAssertEqual(parallel_closest, on_path)
}

for lat in [-10.0, -5.0, 0, 5.0, 10.0] {
let before = CLLocationCoordinate2DMake(lat, -10)
let before_closest = GeometryUtils.closestEdge(from: before, on: path)
XCTAssertNotNil(before_closest);
XCTAssertEqual(before_closest!.coordinate, path.first)
XCTAssertEqual(before_closest, path.first)

let after = CLLocationCoordinate2DMake(lat, 30)
let after_closest = GeometryUtils.closestEdge(from: after, on: path)
XCTAssertNotNil(after_closest)
XCTAssertEqual(after_closest!.coordinate, path.last)
XCTAssertEqual(after_closest, path.last)
}
}

Expand Down Expand Up @@ -397,13 +267,11 @@ class GeometryUtilsTest: XCTestCase {

let n_pole = CLLocationCoordinate2DMake(90, 0)
let n_pole_closest = GeometryUtils.closestEdge(from: n_pole, on: path)
XCTAssertNotNil(n_pole_closest)
XCTAssertEqual(n_pole_closest!.coordinate, path.first)
XCTAssertEqual(n_pole_closest, path.first)

let s_pole = CLLocationCoordinate2DMake(-90, 0)
let s_pole_closest = GeometryUtils.closestEdge(from: s_pole, on: path)
XCTAssertNotNil(s_pole_closest)
XCTAssertEqual(s_pole_closest!.coordinate, path.first)
XCTAssertEqual(s_pole_closest, path.first)
}


Expand Down
Loading

0 comments on commit d80d1b9

Please sign in to comment.