1
1
// Include the C library into this C++ test file.
2
2
extern " C" {
3
- #include " src/olc.h"
3
+ #include " src/olc.h"
4
4
}
5
5
6
+ #include < stdio.h>
7
+ #include < stdlib.h>
6
8
#include < chrono>
7
- #include < cstring>
8
9
#include < cmath>
10
+ #include < cstring>
9
11
#include < fstream>
10
- #include < stdio.h>
11
- #include < stdlib.h>
12
12
#include < string>
13
13
14
14
#include " gtest/gtest.h"
@@ -72,14 +72,12 @@ std::vector<DecodingTestData> GetDecodingDataFromCsv() {
72
72
73
73
TEST_P (DecodingChecks, Decode) {
74
74
DecodingTestData test_data = GetParam ();
75
- OLC_CodeArea expected_area =
76
- OLC_CodeArea{
77
- OLC_LatLon{test_data.lo_lat_deg , test_data.lo_lng_deg },
78
- OLC_LatLon{test_data.hi_lat_deg , test_data.hi_lng_deg },
79
- test_data.length };
80
- OLC_LatLon expected_center = OLC_LatLon{
81
- (test_data.lo_lat_deg + test_data.hi_lat_deg )/2 ,
82
- (test_data.lo_lng_deg + test_data.hi_lng_deg )/2 };
75
+ OLC_CodeArea expected_area = OLC_CodeArea{
76
+ OLC_LatLon{test_data.lo_lat_deg , test_data.lo_lng_deg },
77
+ OLC_LatLon{test_data.hi_lat_deg , test_data.hi_lng_deg }, test_data.length };
78
+ OLC_LatLon expected_center =
79
+ OLC_LatLon{(test_data.lo_lat_deg + test_data.hi_lat_deg ) / 2 ,
80
+ (test_data.lo_lng_deg + test_data.hi_lng_deg ) / 2 };
83
81
OLC_CodeArea got_area;
84
82
OLC_LatLon got_center;
85
83
OLC_Decode (test_data.code .c_str (), 0 , &got_area);
@@ -99,12 +97,12 @@ INSTANTIATE_TEST_SUITE_P(OLC_Tests, DecodingChecks,
99
97
struct EncodingTestData {
100
98
double lat_deg;
101
99
double lng_deg;
100
+ long long int lat_int;
101
+ long long int lng_int;
102
102
size_t length;
103
103
std::string code;
104
104
};
105
105
106
- class EncodingChecks : public ::testing::TestWithParam<EncodingTestData> {};
107
-
108
106
const std::string kEncodingTestsFile = " test_data/encoding.csv" ;
109
107
110
108
std::vector<EncodingTestData> GetEncodingDataFromCsv () {
@@ -115,22 +113,72 @@ std::vector<EncodingTestData> GetEncodingDataFromCsv() {
115
113
EncodingTestData test_data = {};
116
114
test_data.lat_deg = strtod (csv_records[i][0 ].c_str (), nullptr );
117
115
test_data.lng_deg = strtod (csv_records[i][1 ].c_str (), nullptr );
118
- test_data.length = atoi (csv_records[i][2 ].c_str ());
119
- test_data.code = csv_records[i][3 ];
116
+ test_data.lat_int = strtoll (csv_records[i][2 ].c_str (), nullptr , 10 );
117
+ test_data.lng_int = strtoll (csv_records[i][3 ].c_str (), nullptr , 10 );
118
+ test_data.length = atoi (csv_records[i][4 ].c_str ());
119
+ test_data.code = csv_records[i][5 ];
120
120
data_results.push_back (test_data);
121
121
}
122
122
return data_results;
123
123
}
124
124
125
- TEST_P (EncodingChecks, Encode) {
125
+ // TolerantTestParams runs a test with the
126
+ struct TolerantTestParams {
127
+ double allowed_failure_rate;
128
+ std::vector<EncodingTestData> test_data;
129
+ };
130
+
131
+ class TolerantEncodingChecks
132
+ : public ::testing::TestWithParam<TolerantTestParams> {};
133
+
134
+ TEST_P (TolerantEncodingChecks, EncodeDegrees) {
135
+ const TolerantTestParams& test_params = GetParam ();
136
+ int failure_count = 0 ;
137
+
138
+ for (EncodingTestData tc : test_params.test_data ) {
139
+ OLC_LatLon loc = OLC_LatLon{tc.lat_deg , tc.lng_deg };
140
+ char got_code[18 ];
141
+ // Encode the test location and make sure we get the expected code.
142
+ OLC_Encode (&loc, tc.length , got_code, 18 );
143
+ if (tc.code .compare (got_code) != 0 ) {
144
+ failure_count ++;
145
+ printf (" ENCODING FAILURE: Got: '%s', expected: '%s'\n " , got_code, tc.code .c_str ());
146
+ }
147
+ }
148
+ double actual_failure_rate = double (failure_count) / test_params.test_data .size ();
149
+ EXPECT_LE (actual_failure_rate, test_params.allowed_failure_rate )
150
+ << " Failure rate " << actual_failure_rate << " exceeds allowed rate " << test_params.allowed_failure_rate ;
151
+ }
152
+
153
+ // Allow a 5% error rate encoding from degree coordinates (because of floating point precision).
154
+ INSTANTIATE_TEST_SUITE_P (OLC_Tests, TolerantEncodingChecks,
155
+ ::testing::Values (TolerantTestParams{0.05 , GetEncodingDataFromCsv ()}));
156
+
157
+ class EncodingChecks : public ::testing::TestWithParam<EncodingTestData> {};
158
+
159
+ TEST_P (EncodingChecks, OLC_EncodeIntegers) {
126
160
EncodingTestData test_data = GetParam ();
127
- OLC_LatLon loc = OLC_LatLon{test_data.lat_deg , test_data.lng_deg };
161
+ OLC_LatLonIntegers loc =
162
+ OLC_LatLonIntegers{test_data.lat_int , test_data.lng_int };
128
163
char got_code[18 ];
129
164
// Encode the test location and make sure we get the expected code.
130
- OLC_Encode (&loc, test_data.length , got_code, 18 );
165
+ OLC_EncodeIntegers (&loc, test_data.length , got_code, 18 );
131
166
EXPECT_EQ (test_data.code , got_code);
132
167
}
133
168
169
+ TEST_P (EncodingChecks, OLC_LocationToIntegers) {
170
+ EncodingTestData test_data = GetParam ();
171
+ OLC_LatLon loc = OLC_LatLon{test_data.lat_deg , test_data.lng_deg };
172
+ OLC_LatLonIntegers got;
173
+ OLC_LocationToIntegers (&loc, &got);
174
+ // Due to floating point precision limitations, we may get values 1 less than
175
+ // expected.
176
+ EXPECT_LE (got.lat , test_data.lat_int );
177
+ EXPECT_GE (got.lat + 1 , test_data.lat_int );
178
+ EXPECT_LE (got.lon , test_data.lng_int );
179
+ EXPECT_GE (got.lon + 1 , test_data.lng_int );
180
+ }
181
+
134
182
INSTANTIATE_TEST_SUITE_P (OLC_Tests, EncodingChecks,
135
183
::testing::ValuesIn (GetEncodingDataFromCsv()));
136
184
@@ -211,7 +259,8 @@ TEST_P(ShortCodeChecks, ShortCode) {
211
259
// Now extend the code using the reference location and check.
212
260
if (test_data.test_type == " B" || test_data.test_type == " R" ) {
213
261
char got[18 ];
214
- OLC_RecoverNearest (test_data.short_code .c_str (), 0 , &reference_loc, got, 18 );
262
+ OLC_RecoverNearest (test_data.short_code .c_str (), 0 , &reference_loc, got,
263
+ 18 );
215
264
EXPECT_EQ (test_data.full_code , got);
216
265
}
217
266
}
0 commit comments