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
|
|
|
|