|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
declare( strict_types = 1 ); |
|
4
|
|
|
|
|
5
|
|
|
namespace Tests\DataValues\Geo\Parsers; |
|
6
|
|
|
|
|
7
|
|
|
use DataValues\DataValue; |
|
8
|
|
|
use DataValues\Geo\Parsers\GlobeCoordinateParser; |
|
9
|
|
|
use DataValues\Geo\Values\GlobeCoordinateValue; |
|
10
|
|
|
use DataValues\Geo\Values\LatLongValue; |
|
11
|
|
|
use PHPUnit\Framework\TestCase; |
|
12
|
|
|
use ValueParsers\ParseException; |
|
13
|
|
|
use ValueParsers\ParserOptions; |
|
14
|
|
|
|
|
15
|
|
|
/** |
|
16
|
|
|
* @covers \DataValues\Geo\Parsers\GlobeCoordinateParser |
|
17
|
|
|
* @covers \DataValues\Geo\PackagePrivate\LatLongPrecisionParser |
|
18
|
|
|
* @covers \DataValues\Geo\PackagePrivate\PreciseLatLong |
|
19
|
|
|
* @covers \DataValues\Geo\PackagePrivate\PrecisionParser |
|
20
|
|
|
* |
|
21
|
|
|
* @group ValueParsers |
|
22
|
|
|
* @group DataValueExtensions |
|
23
|
|
|
* |
|
24
|
|
|
* @license GPL-2.0-or-later |
|
25
|
|
|
* @author Jeroen De Dauw < [email protected] > |
|
26
|
|
|
* @author Thiemo Kreuz |
|
27
|
|
|
*/ |
|
28
|
|
|
class GlobeCoordinateParserTest extends TestCase { |
|
29
|
|
|
|
|
30
|
|
|
/** |
|
31
|
|
|
* @dataProvider invalidInputProvider |
|
32
|
|
|
*/ |
|
33
|
|
|
public function testParseWithInvalidInputs( $value ) { |
|
34
|
|
|
$this->expectException( ParseException::class ); |
|
35
|
|
|
( new GlobeCoordinateParser() )->parse( $value ); |
|
36
|
|
|
} |
|
37
|
|
|
|
|
38
|
|
|
public function invalidInputProvider() { |
|
39
|
|
|
return [ |
|
40
|
|
|
[ '~=[,,_,,]:3' ], |
|
41
|
|
|
[ 'ohi there' ], |
|
42
|
|
|
]; |
|
43
|
|
|
} |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* @dataProvider validInputProvider |
|
47
|
|
|
*/ |
|
48
|
|
|
public function testParseWithValidInputs( $value, DataValue $expected ) { |
|
49
|
|
|
$actual = ( new GlobeCoordinateParser() )->parse( $value ); |
|
50
|
|
|
$msg = json_encode( $actual->toArray() ) . " should equal\n" |
|
51
|
|
|
. json_encode( $expected->toArray() ); |
|
52
|
|
|
$this->assertTrue( $expected->equals( $actual ), $msg ); |
|
53
|
|
|
} |
|
54
|
|
|
|
|
55
|
|
|
public function validInputProvider() { |
|
56
|
|
|
$argLists = []; |
|
57
|
|
|
|
|
58
|
|
|
$valid = [ |
|
59
|
|
|
// Whitespace |
|
60
|
|
|
"1N 1E\n" => [ 1, 1, 1 ], |
|
61
|
|
|
' 1N 1E ' => [ 1, 1, 1 ], |
|
62
|
|
|
|
|
63
|
|
|
// Float |
|
64
|
|
|
'55.7557860 N, 37.6176330 W' => [ 55.7557860, -37.6176330, 0.000001 ], |
|
65
|
|
|
'55.7557860N,37.6176330W' => [ 55.7557860, -37.6176330, 0.000001 ], |
|
66
|
|
|
'55.7557860, -37.6176330' => [ 55.7557860, -37.6176330, 0.000001 ], |
|
67
|
|
|
'55.7557860, -37.6176330 ' => [ 55.7557860, -37.6176330, 0.000001 ], |
|
68
|
|
|
'55 S, 37.6176330 W' => [ -55, -37.6176330, 0.000001 ], |
|
69
|
|
|
'55 S,37.6176330W' => [ -55, -37.6176330, 0.000001 ], |
|
70
|
|
|
'-55, -37.6176330' => [ -55, -37.6176330, 0.000001 ], |
|
71
|
|
|
'5.5S,37W ' => [ -5.5, -37, 0.1 ], |
|
72
|
|
|
'-5.5,-37 ' => [ -5.5, -37, 0.1 ], |
|
73
|
|
|
'-5.5 -37 ' => [ -5.5, -37, 0.1 ], |
|
74
|
|
|
'4,2' => [ 4, 2, 1 ], |
|
75
|
|
|
'5.5S 37W ' => [ -5.5, -37, 0.1 ], |
|
76
|
|
|
'5.5 S 37 W ' => [ -5.5, -37, 0.1 ], |
|
77
|
|
|
'4 2' => [ 4, 2, 1 ], |
|
78
|
|
|
'S5.5 W37 ' => [ -5.5, -37, 0.1 ], |
|
79
|
|
|
|
|
80
|
|
|
// DD |
|
81
|
|
|
'55.7557860° N, 37.6176330° W' => [ 55.7557860, -37.6176330, 0.000001 ], |
|
82
|
|
|
'55.7557860°, -37.6176330°' => [ 55.7557860, -37.6176330, 0.000001 ], |
|
83
|
|
|
'55.7557860°,-37.6176330°' => [ 55.7557860, -37.6176330, 0.000001 ], |
|
84
|
|
|
'55.7557860°,-37.6176330° ' => [ 55.7557860, -37.6176330, 0.000001 ], |
|
85
|
|
|
'55° S, 37.6176330 ° W' => [ -55, -37.6176330, 0.000001 ], |
|
86
|
|
|
'-55°, -37.6176330 °' => [ -55, -37.6176330, 0.000001 ], |
|
87
|
|
|
'5.5°S,37°W ' => [ -5.5, -37, 0.1 ], |
|
88
|
|
|
'5.5° S,37° W ' => [ -5.5, -37, 0.1 ], |
|
89
|
|
|
'-5.5°,-37° ' => [ -5.5, -37, 0.1 ], |
|
90
|
|
|
'-55° -37.6176330 °' => [ -55, -37.6176330, 0.000001 ], |
|
91
|
|
|
'5.5°S 37°W ' => [ -5.5, -37, 0.1 ], |
|
92
|
|
|
'-5.5 ° -37 ° ' => [ -5.5, -37, 0.1 ], |
|
93
|
|
|
'S5.5° W37°' => [ -5.5, -37, 0.1 ], |
|
94
|
|
|
' S 5.5° W 37°' => [ -5.5, -37, 0.1 ], |
|
95
|
|
|
|
|
96
|
|
|
// DMS |
|
97
|
|
|
'55° 45\' 20.8296", 37° 37\' 3.4788"' => [ 55.755786, 37.617633, 0.0001 / 3600 ], |
|
98
|
|
|
'55° 45\' 20.8296", -37° 37\' 3.4788"' => [ 55.755786, -37.617633, 0.0001 / 3600 ], |
|
99
|
|
|
'-55° 45\' 20.8296", -37° 37\' 3.4788"' => [ -55.755786, -37.617633, 0.0001 / 3600 ], |
|
100
|
|
|
'-55° 45\' 20.8296", 37° 37\' 3.4788"' => [ -55.755786, 37.617633, 0.0001 / 3600 ], |
|
101
|
|
|
'-55° 45\' 20.8296", 37° 37\' 3.4788" ' => [ -55.755786, 37.617633, 0.0001 / 3600 ], |
|
102
|
|
|
'55° 0\' 0", 37° 0\' 0"' => [ 55, 37, 1 / 3600 ], |
|
103
|
|
|
'55° 30\' 0", 37° 30\' 0"' => [ 55.5, 37.5, 1 / 3600 ], |
|
104
|
|
|
'55° 0\' 18", 37° 0\' 18"' => [ 55.005, 37.005, 1 / 3600 ], |
|
105
|
|
|
' 55° 0\' 18", 37° 0\' 18"' => [ 55.005, 37.005, 1 / 3600 ], |
|
106
|
|
|
'0° 0\' 0", 0° 0\' 0"' => [ 0, 0, 1 / 3600 ], |
|
107
|
|
|
'0° 0\' 18" N, 0° 0\' 18" E' => [ 0.005, 0.005, 1 / 3600 ], |
|
108
|
|
|
' 0° 0\' 18" S , 0° 0\' 18" W ' => [ -0.005, -0.005, 1 / 3600 ], |
|
109
|
|
|
'0° 0′ 18″ N, 0° 0′ 18″ E' => [ 0.005, 0.005, 1 / 3600 ], |
|
110
|
|
|
'0° 0\' 18" N 0° 0\' 18" E' => [ 0.005, 0.005, 1 / 3600 ], |
|
111
|
|
|
' 0 ° 0 \' 18 " S 0 ° 0 \' 18 " W ' => [ -0.005, -0.005, 1 / 3600 ], |
|
112
|
|
|
'0° 0′ 18″ N 0° 0′ 18″ E' => [ 0.005, 0.005, 1 / 3600 ], |
|
113
|
|
|
'N 0° 0\' 18" E 0° 0\' 18"' => [ 0.005, 0.005, 1 / 3600 ], |
|
114
|
|
|
'N0°0\'18"E0°0\'18"' => [ 0.005, 0.005, 1 / 3600 ], |
|
115
|
|
|
'N0°0\'18" E0°0\'18"' => [ 0.005, 0.005, 1 / 3600 ], |
|
116
|
|
|
|
|
117
|
|
|
// DM |
|
118
|
|
|
'55° 0\', 37° 0\'' => [ 55, 37, 1 / 60 ], |
|
119
|
|
|
'55° 30\', 37° 30\'' => [ 55.5, 37.5, 1 / 60 ], |
|
120
|
|
|
'0° 0\', 0° 0\'' => [ 0, 0, 1 / 60 ], |
|
121
|
|
|
' 0° 0\', 0° 0\'' => [ 0, 0, 1 / 60 ], |
|
122
|
|
|
' 0° 0\', 0° 0\' ' => [ 0, 0, 1 / 60 ], |
|
123
|
|
|
'-55° 30\', -37° 30\'' => [ -55.5, -37.5, 1 / 60 ], |
|
124
|
|
|
'0° 0.3\' S, 0° 0.3\' W' => [ -0.005, -0.005, 1 / 3600 ], |
|
125
|
|
|
'-55° 30′, -37° 30′' => [ -55.5, -37.5, 1 / 60 ], |
|
126
|
|
|
'-55 ° 30 \' -37 ° 30 \'' => [ -55.5, -37.5, 1 / 60 ], |
|
127
|
|
|
'0° 0.3\' S 0° 0.3\' W' => [ -0.005, -0.005, 1 / 3600 ], |
|
128
|
|
|
'-55° 30′ -37° 30′' => [ -55.5, -37.5, 1 / 60 ], |
|
129
|
|
|
'S 0° 0.3\' W 0° 0.3\'' => [ -0.005, -0.005, 1 / 3600 ], |
|
130
|
|
|
'S0°0.3\'W0°0.3\'' => [ -0.005, -0.005, 1 / 3600 ], |
|
131
|
|
|
'S0°0.3\' W0°0.3\'' => [ -0.005, -0.005, 1 / 3600 ], |
|
132
|
|
|
]; |
|
133
|
|
|
|
|
134
|
|
|
foreach ( $valid as $value => $expected ) { |
|
135
|
|
|
$expected = new GlobeCoordinateValue( new LatLongValue( $expected[0], $expected[1] ), $expected[2] ); |
|
136
|
|
|
$argLists[] = [ (string)$value, $expected ]; |
|
137
|
|
|
} |
|
138
|
|
|
|
|
139
|
|
|
return $argLists; |
|
140
|
|
|
} |
|
141
|
|
|
|
|
142
|
|
|
public function testWithGlobeOptionMatchingTheDefault() { |
|
143
|
|
|
$parser = new GlobeCoordinateParser( new ParserOptions( [ |
|
144
|
|
|
'globe' => 'http://www.wikidata.org/entity/Q2' |
|
145
|
|
|
] ) ); |
|
146
|
|
|
|
|
147
|
|
|
$this->assertEquals( |
|
148
|
|
|
new GlobeCoordinateValue( |
|
149
|
|
|
new LatLongValue( 55.7557860, -37.6176330 ), |
|
150
|
|
|
0.000001, |
|
151
|
|
|
'http://www.wikidata.org/entity/Q2' |
|
152
|
|
|
), |
|
153
|
|
|
$parser->parse( '55.7557860° N, 37.6176330° W' ) |
|
154
|
|
|
); |
|
155
|
|
|
} |
|
156
|
|
|
|
|
157
|
|
|
public function testWithGlobeOptionDifferingFromTheDefault() { |
|
158
|
|
|
$parser = new GlobeCoordinateParser( new ParserOptions( [ |
|
159
|
|
|
'globe' => 'http://www.wikidata.org/entity/Q111' |
|
160
|
|
|
] ) ); |
|
161
|
|
|
|
|
162
|
|
|
$this->assertEquals( |
|
163
|
|
|
new GlobeCoordinateValue( |
|
164
|
|
|
new LatLongValue( 60.5, 260 ), |
|
165
|
|
|
0.1, |
|
166
|
|
|
'http://www.wikidata.org/entity/Q111' |
|
167
|
|
|
), |
|
168
|
|
|
$parser->parse( '60.5, 260' ) |
|
169
|
|
|
); |
|
170
|
|
|
} |
|
171
|
|
|
|
|
172
|
|
|
public function testWithoutGlobeOption() { |
|
173
|
|
|
$parser = new GlobeCoordinateParser(); |
|
174
|
|
|
|
|
175
|
|
|
$this->assertEquals( |
|
176
|
|
|
new GlobeCoordinateValue( |
|
177
|
|
|
new LatLongValue( 40.2, 22.5 ), |
|
178
|
|
|
0.1, |
|
179
|
|
|
'http://www.wikidata.org/entity/Q2' |
|
180
|
|
|
), |
|
181
|
|
|
$parser->parse( '40.2, 22.5' ) |
|
182
|
|
|
); |
|
183
|
|
|
} |
|
184
|
|
|
|
|
185
|
|
|
/** |
|
186
|
|
|
* @dataProvider precisionDetectionProvider |
|
187
|
|
|
*/ |
|
188
|
|
|
public function testPrecisionDetection( $value, $expected ) { |
|
189
|
|
|
$parser = new GlobeCoordinateParser(); |
|
190
|
|
|
$globeCoordinateValue = $parser->parse( $value ); |
|
191
|
|
|
|
|
192
|
|
|
$this->assertSame( (float)$expected, $globeCoordinateValue->getPrecision() ); |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
public function precisionDetectionProvider() { |
|
196
|
|
|
return [ |
|
197
|
|
|
// Float |
|
198
|
|
|
[ '10 20', 1 ], |
|
199
|
|
|
[ '1 2', 1 ], |
|
200
|
|
|
[ '1.3 2.4', 0.1 ], |
|
201
|
|
|
[ '1.3 20', 0.1 ], |
|
202
|
|
|
[ '10 2.4', 0.1 ], |
|
203
|
|
|
[ '1.35 2.46', 0.01 ], |
|
204
|
|
|
[ '1.357 2.468', 0.001 ], |
|
205
|
|
|
[ '1.3579 2.468', 0.0001 ], |
|
206
|
|
|
[ '1.00001 2.00001', 0.00001 ], |
|
207
|
|
|
[ '1.000001 2.000001', 0.000001 ], |
|
208
|
|
|
[ '1.0000001 2.0000001', 0.0000001 ], |
|
209
|
|
|
[ '1.00000001 2.00000001', 0.00000001 ], |
|
210
|
|
|
[ '1.000000001 2.000000001', 1 ], |
|
211
|
|
|
[ '1.555555555 2.555555555', 0.00000001 ], |
|
212
|
|
|
|
|
213
|
|
|
// Dd |
|
214
|
|
|
[ '10° 20°', 1 ], |
|
215
|
|
|
[ '1° 2°', 1 ], |
|
216
|
|
|
[ '1.3° 2.4°', 0.1 ], |
|
217
|
|
|
[ '1.3° 20°', 0.1 ], |
|
218
|
|
|
[ '10° 2.4°', 0.1 ], |
|
219
|
|
|
[ '1.35° 2.46°', 0.01 ], |
|
220
|
|
|
[ '1.357° 2.468°', 0.001 ], |
|
221
|
|
|
[ '1.3579° 2.468°', 0.0001 ], |
|
222
|
|
|
[ '1.00001° 2.00001°', 0.00001 ], |
|
223
|
|
|
[ '1.000001° 2.000001°', 0.000001 ], |
|
224
|
|
|
[ '1.0000001° 2.0000001°', 0.0000001 ], |
|
225
|
|
|
[ '1.00000001° 2.00000001°', 0.00000001 ], |
|
226
|
|
|
[ '1.000000001° 2.000000001°', 1 ], |
|
227
|
|
|
[ '1.555555555° 2.555555555°', 0.00000001 ], |
|
228
|
|
|
|
|
229
|
|
|
// Dm |
|
230
|
|
|
[ '1°3\' 2°4\'', 1 / 60 ], |
|
231
|
|
|
[ '1°3\' 2°0\'', 1 / 60 ], |
|
232
|
|
|
[ '1°0\' 2°4\'', 1 / 60 ], |
|
233
|
|
|
[ '1°3.5\' 2°4.6\'', 1 / 3600 ], |
|
234
|
|
|
[ '1°3.57\' 2°4.68\'', 1 / 36000 ], |
|
235
|
|
|
[ '1°3.579\' 2°4.68\'', 1 / 360000 ], |
|
236
|
|
|
[ '1°3.0001\' 2°4.0001\'', 1 / 3600000 ], |
|
237
|
|
|
[ '1°3.00001\' 2°4.00001\'', 1 / 36000000 ], |
|
238
|
|
|
[ '1°3.000001\' 2°4.000001\'', 1 / 36000000 ], |
|
239
|
|
|
[ '1°3.0000001\' 2°4.0000001\'', 1 / 60 ], |
|
240
|
|
|
[ '1°3.5555555\' 2°4.5555555\'', 1 / 36000000 ], |
|
241
|
|
|
|
|
242
|
|
|
// Dms |
|
243
|
|
|
[ '1°3\'5" 2°4\'6"', 1 / 3600 ], |
|
244
|
|
|
[ '1°3\'5" 2°0\'0"', 1 / 3600 ], |
|
245
|
|
|
[ '1°0\'0" 2°4\'6"', 1 / 3600 ], |
|
246
|
|
|
[ '1°3\'0" 2°4\'0"', 1 / 3600 ], |
|
247
|
|
|
[ '1°3\'5.7" 2°4\'6.8"', 1 / 36000 ], |
|
248
|
|
|
[ '1°3\'5.79" 2°4\'6.8"', 1 / 360000 ], |
|
249
|
|
|
[ '1°3\'5.001" 2°4\'6.001"', 1 / 3600000 ], |
|
250
|
|
|
[ '1°3\'5.0001" 2°4\'6.0001"', 1 / 36000000 ], |
|
251
|
|
|
[ '1°3\'5.00001" 2°4\'6.00001"', 1 / 3600 ], |
|
252
|
|
|
[ '1°3\'5.55555" 2°4\'6.55555"', 1 / 36000000 ], |
|
253
|
|
|
|
|
254
|
|
|
/** |
|
255
|
|
|
* @fixme What do the users expect in this case, 1/3600 or 1/360000? |
|
256
|
|
|
* @see https://bugzilla.wikimedia.org/show_bug.cgi?id=64820 |
|
257
|
|
|
*/ |
|
258
|
|
|
[ '47°42\'0.00"N, 15°27\'0.00"E', 1 / 3600 ], |
|
259
|
|
|
]; |
|
260
|
|
|
} |
|
261
|
|
|
|
|
262
|
|
|
public function testCanParseSuccessiveValues() { |
|
263
|
|
|
$parser = new GlobeCoordinateParser(); |
|
264
|
|
|
|
|
265
|
|
|
$this->assertEquals( |
|
266
|
|
|
$parser->parse( 'S5.5 W37' ), |
|
267
|
|
|
$parser->parse( 'S5.5 W37' ) |
|
268
|
|
|
); |
|
269
|
|
|
|
|
270
|
|
|
$this->assertEquals( |
|
271
|
|
|
$parser->parse( '55° 0\' 0", 37° 0\' 0"' ), |
|
272
|
|
|
$parser->parse( '55° 0\' 0", 37° 0\' 0"' ) |
|
273
|
|
|
); |
|
274
|
|
|
} |
|
275
|
|
|
|
|
276
|
|
|
} |
|
277
|
|
|
|