response_test.go
1package graphhopper
2
3import (
4 "encoding/json"
5 "testing"
6
7 "github.com/stretchr/testify/assert"
8 "github.com/stretchr/testify/require"
9)
10
11// helper to create GeoJSON LineString from coordinates
12func mustMarshalGeoJSON(coords [][]float64) json.RawMessage {
13 geoJSON := map[string]interface{}{
14 "type": "LineString",
15 "coordinates": coords,
16 }
17 b, _ := json.Marshal(geoJSON)
18 return b
19}
20
21func TestResponse_decode_points_and_elevation(t *testing.T) {
22 // Graphhopper API returns GeoJSON LineString: {"type":"LineString","coordinates":[[lon, lat, elevation], ...]}
23 points := [][]float64{
24 {-74.006, 40.7128, 10.5}, // NYC point with elevation
25 {-118.2437, 34.0522, 89.0}, // LA point with elevation
26 {-87.6298, 41.8781, 181.0}, // Chicago point with elevation
27 }
28 pointsJSON := mustMarshalGeoJSON(points)
29
30 resp := &Response{
31 Paths: []Path{
32 {
33 Distance: 1000.0,
34 Time: 60000,
35 Points: pointsJSON,
36 PointsEncoded: false,
37 },
38 },
39 }
40
41 // Test Points()
42 decoded, err := resp.Points()
43 require.NoError(t, err)
44 assert.Len(t, decoded, 3, "should have 3 points")
45
46 // Verify each point has lon, lat (not elevation)
47 assert.Equal(t, []float64{-74.006, 40.7128}, decoded[0])
48 assert.Equal(t, []float64{-118.2437, 34.0522}, decoded[1])
49 assert.Equal(t, []float64{-87.6298, 41.8781}, decoded[2])
50
51 // Test Elevation()
52 elevation, err := resp.Elevation()
53 require.NoError(t, err)
54 assert.Len(t, elevation, 3, "should have 3 elevation values")
55 assert.Equal(t, []float64{10.5, 89.0, 181.0}, elevation)
56}
57
58func TestResponse_decode_points_without_elevation(t *testing.T) {
59 // Points without elevation as GeoJSON: {"type":"LineString","coordinates":[[lon, lat], ...]}
60 points := [][]float64{
61 {-74.006, 40.7128},
62 {-118.2437, 34.0522},
63 }
64 pointsJSON := mustMarshalGeoJSON(points)
65
66 resp := &Response{
67 Paths: []Path{
68 {
69 Points: pointsJSON,
70 PointsEncoded: false,
71 },
72 },
73 }
74
75 decoded, err := resp.Points()
76 require.NoError(t, err)
77 assert.Len(t, decoded, 2)
78 assert.Equal(t, []float64{-74.006, 40.7128}, decoded[0])
79 assert.Equal(t, []float64{-118.2437, 34.0522}, decoded[1])
80
81 elevation, err := resp.Elevation()
82 require.NoError(t, err)
83 assert.Empty(t, elevation, "should have no elevation values when not provided")
84}
85
86func TestResponse_decode_multiple_paths(t *testing.T) {
87 // First path as GeoJSON
88 points1 := [][]float64{
89 {-74.006, 40.7128, 10.0},
90 {-75.0, 41.0, 20.0},
91 }
92 points1JSON := mustMarshalGeoJSON(points1)
93
94 // Second path as GeoJSON
95 points2 := [][]float64{
96 {-118.2437, 34.0522, 50.0},
97 {-119.0, 35.0, 60.0},
98 }
99 points2JSON := mustMarshalGeoJSON(points2)
100
101 resp := &Response{
102 Paths: []Path{
103 {
104 Points: points1JSON,
105 PointsEncoded: false,
106 },
107 {
108 Points: points2JSON,
109 PointsEncoded: false,
110 },
111 },
112 }
113
114 // Should combine all points from all paths
115 decoded, err := resp.Points()
116 require.NoError(t, err)
117 assert.Len(t, decoded, 4, "should have 4 points total (2 from each path)")
118 assert.Equal(t, []float64{-74.006, 40.7128}, decoded[0])
119 assert.Equal(t, []float64{-75.0, 41.0}, decoded[1])
120 assert.Equal(t, []float64{-118.2437, 34.0522}, decoded[2])
121 assert.Equal(t, []float64{-119.0, 35.0}, decoded[3])
122
123 // Should combine all elevation values
124 elevation, err := resp.Elevation()
125 require.NoError(t, err)
126 assert.Len(t, elevation, 4)
127 assert.Equal(t, []float64{10.0, 20.0, 50.0, 60.0}, elevation)
128}
129
130func TestResponse_decode_empty_points(t *testing.T) {
131 points := [][]float64{}
132 pointsJSON := mustMarshalGeoJSON(points)
133
134 resp := &Response{
135 Paths: []Path{
136 {
137 Points: pointsJSON,
138 PointsEncoded: false,
139 },
140 },
141 }
142
143 decoded, err := resp.Points()
144 require.NoError(t, err)
145 assert.Empty(t, decoded)
146
147 elevation, err := resp.Elevation()
148 require.NoError(t, err)
149 assert.Empty(t, elevation)
150}
151
152func TestResponse_decode_memoization(t *testing.T) {
153 points := [][]float64{
154 {-74.006, 40.7128, 10.5},
155 }
156 pointsJSON := mustMarshalGeoJSON(points)
157
158 resp := &Response{
159 Paths: []Path{
160 {
161 Points: pointsJSON,
162 PointsEncoded: false,
163 },
164 },
165 }
166
167 // First call
168 decoded1, err := resp.Points()
169 require.NoError(t, err)
170 assert.Len(t, decoded1, 1)
171
172 // Second call should return same memoized result
173 decoded2, err := resp.Points()
174 require.NoError(t, err)
175 assert.Len(t, decoded2, 1)
176
177 // Should be the same underlying array
178 assert.Equal(t, decoded1, decoded2)
179}