Completed
Pull Request — master (#74)
by no
04:51 queued 02:31
created

testParseWithValidInputs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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