@@ -4,7 +4,10 @@ use std::time::Instant;
44
55use csv_reader:: CSVReader ;
66use geo:: Point ;
7- use open_location_code:: { decode, encode, is_full, is_short, is_valid, recover_nearest, shorten} ;
7+ use open_location_code:: {
8+ decode, encode, encode_integers, is_full, is_short, is_valid, point_to_integers,
9+ recover_nearest, shorten,
10+ } ;
811use rand:: random_range;
912
1013/// CSVReader is written to swallow errors; as such, we might "pass" tests because we didn't
@@ -59,18 +62,87 @@ fn decode_test() {
5962#[ test]
6063fn encode_test ( ) {
6164 let mut tested = 0 ;
65+ let mut errors = 0 ;
66+ // Allow a small proportion of errors due to floating point.
67+ let allowed_error_rate = 0.05 ;
6268 for line in CSVReader :: new ( "encoding.csv" ) {
6369 if line. chars ( ) . count ( ) == 0 {
6470 continue ;
6571 }
6672 let cols: Vec < & str > = line. split ( ',' ) . collect ( ) ;
6773 let lat = cols[ 0 ] . parse :: < f64 > ( ) . unwrap ( ) ;
6874 let lng = cols[ 1 ] . parse :: < f64 > ( ) . unwrap ( ) ;
69- let len = cols[ 2 ] . parse :: < usize > ( ) . unwrap ( ) ;
70- let code = cols[ 3 ] ;
75+ let len = cols[ 4 ] . parse :: < usize > ( ) . unwrap ( ) ;
76+ let code = cols[ 5 ] ;
77+
78+ let got = encode ( Point :: new ( lng, lat) , len) ;
79+ if got != code {
80+ errors += 1 ;
81+ println ! (
82+ "encode(Point::new({}, {}), {}) want {}, got {}" ,
83+ lng, lat, len, code, got
84+ ) ;
85+ }
86+
87+ tested += 1 ;
88+ }
89+ assert ! (
90+ errors as f32 / tested as f32 <= allowed_error_rate,
91+ "too many encoding errors ({})" ,
92+ errors
93+ ) ;
94+ assert ! ( tested > 0 ) ;
95+ }
96+
97+ #[ test]
98+ fn point_to_integers_test ( ) {
99+ let mut tested = 0 ;
100+ for line in CSVReader :: new ( "encoding.csv" ) {
101+ if line. chars ( ) . count ( ) == 0 {
102+ continue ;
103+ }
104+ let cols: Vec < & str > = line. split ( ',' ) . collect ( ) ;
105+ let lat_deg = cols[ 0 ] . parse :: < f64 > ( ) . unwrap ( ) ;
106+ let lng_deg = cols[ 1 ] . parse :: < f64 > ( ) . unwrap ( ) ;
107+ let lat_int = cols[ 2 ] . parse :: < i64 > ( ) . unwrap ( ) ;
108+ let lng_int = cols[ 3 ] . parse :: < i64 > ( ) . unwrap ( ) ;
109+
110+ let ( got_lat, got_lng) = point_to_integers ( Point :: new ( lng_deg, lat_deg) ) ;
111+ assert ! (
112+ got_lat >= lat_int - 1 && got_lat <= lat_int,
113+ "converting lat={}, want={}, got={}" ,
114+ lat_deg,
115+ lat_int,
116+ got_lat
117+ ) ;
118+ assert ! (
119+ got_lng >= lng_int - 1 && got_lng <= lng_int,
120+ "converting lng={}, want={}, got={}" ,
121+ lng_deg,
122+ lng_int,
123+ got_lng
124+ ) ;
125+
126+ tested += 1 ;
127+ }
128+ assert ! ( tested > 0 ) ;
129+ }
130+
131+ #[ test]
132+ fn encode_integers_test ( ) {
133+ let mut tested = 0 ;
134+ for line in CSVReader :: new ( "encoding.csv" ) {
135+ if line. chars ( ) . count ( ) == 0 {
136+ continue ;
137+ }
138+ let cols: Vec < & str > = line. split ( ',' ) . collect ( ) ;
139+ let lat = cols[ 2 ] . parse :: < i64 > ( ) . unwrap ( ) ;
140+ let lng = cols[ 3 ] . parse :: < i64 > ( ) . unwrap ( ) ;
141+ let len = cols[ 4 ] . parse :: < usize > ( ) . unwrap ( ) ;
142+ let code = cols[ 5 ] ;
71143
72144 assert_eq ! (
73- encode ( Point :: new ( lng , lat ) , len) ,
145+ encode_integers ( lat , lng , len) ,
74146 code,
75147 "encoding lat={},lng={},len={}" ,
76148 lat,
0 commit comments