Completed
Pull Request — master (#168)
by Jeroen De
02:05
created

testWithGlobeOptionDifferingFromTheDefault()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

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