Completed
Push — master ( 5763d0...f2497e )
by
unknown
05:28 queued 16s
created

QuantityValueTest::transformProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 71
Code Lines 50

Duplication

Lines 0
Ratio 0 %

Importance

Changes 3
Bugs 1 Features 0
Metric Value
c 3
b 1
f 0
dl 0
loc 71
rs 9.1369
cc 1
eloc 50
nc 1
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace DataValues\Tests;
4
5
use DataValues\DecimalValue;
6
use DataValues\QuantityValue;
7
8
/**
9
 * @covers DataValues\QuantityValue
10
 *
11
 * @group DataValue
12
 * @group DataValueExtensions
13
 *
14
 * @license GPL-2.0+
15
 * @author Daniel Kinzler
16
 */
17
class QuantityValueTest extends DataValueTest {
18
19
	/**
20
	 * @see DataValueTest::getClass
21
	 *
22
	 * @return string
23
	 */
24
	public function getClass() {
25
		return 'DataValues\QuantityValue';
26
	}
27
28
	public function validConstructorArgumentsProvider() {
29
		$argLists = array();
30
31
		$argLists[] = array( new DecimalValue( '+42' ), '1', new DecimalValue( '+42' ), new DecimalValue( '+42' ) );
32
		$argLists[] = array( new DecimalValue( '+0.01' ), '1', new DecimalValue( '+0.02' ), new DecimalValue( '+0.0001' ) );
33
		$argLists[] = array( new DecimalValue( '-0.5' ), '1', new DecimalValue( '+0.02' ), new DecimalValue( '-0.7' ) );
34
35
		return $argLists;
36
	}
37
38
	public function invalidConstructorArgumentsProvider() {
39
		$argLists = array();
40
41
		$argLists[] = array( new DecimalValue( '+0' ), '', new DecimalValue( '+0' ), new DecimalValue( '+0' ) );
42
		$argLists[] = array( new DecimalValue( '+0' ), 1, new DecimalValue( '+0' ), new DecimalValue( '+0' ) );
43
44
		$argLists[] = array( new DecimalValue( '+0' ), '1', new DecimalValue( '-0.001' ), new DecimalValue( '-1' ) );
45
		$argLists[] = array( new DecimalValue( '+0' ), '1', new DecimalValue( '+1' ), new DecimalValue( '+0.001' ) );
46
47
		return $argLists;
48
	}
49
50
	/**
51
	 * @dataProvider instanceProvider
52
	 */
53
	public function testGetValue( QuantityValue $quantity, array $arguments ) {
54
		$this->assertSame( $quantity, $quantity->getValue() );
55
	}
56
57
	/**
58
	 * @dataProvider instanceProvider
59
	 */
60
	public function testGetAmount( QuantityValue $quantity, array $arguments ) {
61
		$this->assertSame( $arguments[0], $quantity->getAmount() );
62
	}
63
64
	/**
65
	 * @dataProvider instanceProvider
66
	 */
67
	public function testGetUnit( QuantityValue $quantity, array $arguments ) {
68
		$this->assertSame( $arguments[1], $quantity->getUnit() );
69
	}
70
71
	/**
72
	 * @dataProvider instanceProvider
73
	 */
74
	public function testGetUpperBound( QuantityValue $quantity, array $arguments ) {
75
		$this->assertSame( $arguments[2], $quantity->getUpperBound() );
76
	}
77
78
	/**
79
	 * @dataProvider instanceProvider
80
	 */
81
	public function testGetLowerBound( QuantityValue $quantity, array $arguments ) {
82
		$this->assertSame( $arguments[3], $quantity->getLowerBound() );
83
	}
84
85
	/**
86
	 * @dataProvider newFromNumberProvider
87
	 */
88
	public function testNewFromNumber( $amount, $unit, $upperBound, $lowerBound, QuantityValue $expected ) {
89
		$quantity = QuantityValue::newFromNumber( $amount, $unit, $upperBound, $lowerBound );
90
91
		$this->assertEquals( $expected->getAmount()->getValue(), $quantity->getAmount()->getValue() );
92
		$this->assertEquals( $expected->getUpperBound()->getValue(), $quantity->getUpperBound()->getValue() );
93
		$this->assertEquals( $expected->getLowerBound()->getValue(), $quantity->getLowerBound()->getValue() );
94
	}
95
96
	public function newFromNumberProvider() {
97
		return array(
98
			array(
99
				42, '1', null, null,
100
				new QuantityValue( new DecimalValue( '+42' ), '1', new DecimalValue( '+42' ), new DecimalValue( '+42' ) )
101
			),
102
			array(
103
				-0.05, '1', null, null,
104
				new QuantityValue( new DecimalValue( '-0.05' ), '1', new DecimalValue( '-0.05' ), new DecimalValue( '-0.05' ) )
105
			),
106
			array(
107
				0, 'm', 0.5, -0.5,
108
				new QuantityValue( new DecimalValue( '+0' ), 'm', new DecimalValue( '+0.5' ), new DecimalValue( '-0.5' ) )
109
			),
110
			array(
111
				'+23', '1', null, null,
112
				new QuantityValue( new DecimalValue( '+23' ), '1', new DecimalValue( '+23' ), new DecimalValue( '+23' ) )
113
			),
114
			array(
115
				'+42', '1', '+43', '+41',
116
				new QuantityValue( new DecimalValue( '+42' ), '1', new DecimalValue( '+43' ), new DecimalValue( '+41' ) )
117
			),
118
			array(
119
				'-0.05', 'm', '-0.04', '-0.06',
120
				new QuantityValue( new DecimalValue( '-0.05' ), 'm', new DecimalValue( '-0.04' ), new DecimalValue( '-0.06' ) )
121
			),
122
			array(
123
				new DecimalValue( '+42' ), '1', new DecimalValue( 43 ), new DecimalValue( 41.0 ),
124
				new QuantityValue( new DecimalValue( '+42' ), '1', new DecimalValue( 43 ), new DecimalValue( 41.0 ) )
125
			),
126
		);
127
	}
128
129
	/**
130
	 * @dataProvider validArraySerializationProvider
131
	 */
132
	public function testNewFromArray( $data, QuantityValue $expected ) {
133
		$value = QuantityValue::newFromArray( $data );
134
		$this->assertTrue( $expected->equals( $value ), $value . ' should equal ' . $expected );
135
	}
136
137
	public function validArraySerializationProvider() {
138
		return array(
139
			'complete' => array(
140
				array(
141
					'amount' => '+2',
142
					'unit' => '1',
143
					'upperBound' => '+2.5',
144
					'lowerBound' => '+1.5',
145
				),
146
				QuantityValue::newFromNumber( '+2', '1', '+2.5', '+1.5' )
147
			),
148
		);
149
	}
150
151
	/**
152
	 * @dataProvider invalidArraySerializationProvider
153
	 */
154
	public function testNewFromArray_failure( $data ) {
155
		$this->setExpectedException( 'DataValues\IllegalValueException' );
156
		QuantityValue::newFromArray( $data );
157
	}
158
159
	public function invalidArraySerializationProvider() {
160
		return array(
161
			'no-amount' => array(
162
				array(
163
					'unit' => '1',
164
					'upperBound' => '+2.5',
165
					'lowerBound' => '+1.5',
166
				)
167
			),
168
			'no-unit' => array(
169
				array(
170
					'amount' => '+2',
171
					'upperBound' => '+2.5',
172
					'lowerBound' => '+1.5',
173
				)
174
			),
175
			'no-upperBound' => array(
176
				array(
177
					'amount' => '+2',
178
					'unit' => '1',
179
					'lowerBound' => '+1.5',
180
				)
181
			),
182
			'no-lowerBound' => array(
183
				array(
184
					'amount' => '+2',
185
					'unit' => '1',
186
					'upperBound' => '+2.5',
187
				)
188
			),
189
			'unbounded' => array(
190
				array(
191
					'amount' => '+2',
192
					'unit' => '1',
193
				)
194
			),
195
			'bad-amount' => array(
196
				array(
197
					'amount' => 'x',
198
					'unit' => '1',
199
					'upperBound' => '+2.5',
200
					'lowerBound' => '+1.5',
201
				)
202
			),
203
			'bad-upperBound' => array(
204
				array(
205
					'amount' => '+2',
206
					'unit' => '1',
207
					'upperBound' => 'x',
208
					'lowerBound' => '+1.5',
209
				)
210
			),
211
			'bad-lowerBound' => array(
212
				array(
213
					'amount' => '+2',
214
					'unit' => '1',
215
					'upperBound' => '+2.5',
216
					'lowerBound' => 'x',
217
				)
218
			),
219
		);
220
	}
221
222
	/**
223
	 * @see https://phabricator.wikimedia.org/T110728
224
	 * @see http://www.regular-expressions.info/anchors.html#realend
225
	 */
226
	public function testTrailingNewlineRobustness() {
227
		$value = QuantityValue::newFromArray( array(
228
			'amount' => "-0.0\n",
229
			'unit' => "1\n",
230
			'upperBound' => "-0.0\n",
231
			'lowerBound' => "-0.0\n",
232
		) );
233
234
		$this->assertSame( array(
235
			'amount' => '+0.0',
236
			'unit' => "1\n",
237
			'upperBound' => '+0.0',
238
			'lowerBound' => '+0.0',
239
		), $value->getArrayValue() );
240
	}
241
242
	/**
243
	 * @dataProvider instanceProvider
244
	 */
245
	public function testGetSortKey( QuantityValue $quantity ) {
246
		$this->assertSame( $quantity->getAmount()->getValueFloat(), $quantity->getSortKey() );
247
	}
248
249
	/**
250
	 * @dataProvider getUncertaintyProvider
251
	 */
252
	public function testGetUncertainty( QuantityValue $quantity, $expected ) {
253
		$this->assertSame( $expected, $quantity->getUncertainty() );
254
	}
255
256
	public function getUncertaintyProvider() {
257
		return array(
258
			array( QuantityValue::newFromNumber( '+0', '1', '+0', '+0' ), 0.0 ),
259
260
			array( QuantityValue::newFromNumber( '+0', '1', '+1', '-1' ), 2.0 ),
261
			array( QuantityValue::newFromNumber( '+0.00', '1', '+0.01', '-0.01' ), 0.02 ),
262
			array( QuantityValue::newFromNumber( '+100', '1', '+101', '+99' ), 2.0 ),
263
			array( QuantityValue::newFromNumber( '+100.0', '1', '+100.1', '+99.9' ), 0.2 ),
264
			array( QuantityValue::newFromNumber( '+12.34', '1', '+12.35', '+12.33' ), 0.02 ),
265
266
			array( QuantityValue::newFromNumber( '+0', '1', '+0.2', '-0.6' ), 0.8 ),
267
			array( QuantityValue::newFromNumber( '+7.3', '1', '+7.7', '+5.2' ), 2.5 ),
268
		);
269
	}
270
271
	/**
272
	 * @dataProvider getUncertaintyMarginProvider
273
	 */
274
	public function testGetUncertaintyMargin( QuantityValue $quantity, $expected ) {
275
		$this->assertSame( $expected, $quantity->getUncertaintyMargin()->getValue() );
276
	}
277
278
	public function getUncertaintyMarginProvider() {
279
		return array(
280
			array( QuantityValue::newFromNumber( '+0', '1', '+1', '-1' ), '+1' ),
281
			array( QuantityValue::newFromNumber( '+0.00', '1', '+0.01', '-0.01' ), '+0.01' ),
282
283
			array( QuantityValue::newFromNumber( '-1', '1', '-1', '-1' ), '+0' ),
284
285
			array( QuantityValue::newFromNumber( '+0', '1', '+0.2', '-0.6' ), '+0.6' ),
286
			array( QuantityValue::newFromNumber( '+7.5', '1', '+7.5', '+5.5' ), '+2.0' ),
287
			array( QuantityValue::newFromNumber( '+11.5', '1', '+15', '+10.5' ), '+3.5' ),
288
		);
289
	}
290
291
	/**
292
	 * @dataProvider getOrderOfUncertaintyProvider
293
	 */
294
	public function testGetOrderOfUncertainty( QuantityValue $quantity, $expected ) {
295
		$this->assertSame( $expected, $quantity->getOrderOfUncertainty() );
296
	}
297
298
	public function getOrderOfUncertaintyProvider() {
299
		return array(
300
			0 => array( QuantityValue::newFromNumber( '+0' ), 0 ),
301
			1 => array( QuantityValue::newFromNumber( '-123' ), 0 ),
302
			2 => array( QuantityValue::newFromNumber( '-1.23' ), -2 ),
303
304
			10 => array( QuantityValue::newFromNumber( '-100', '1', '-99', '-101' ), 0 ),
305
			11 => array( QuantityValue::newFromNumber( '+0.00', '1', '+0.01', '-0.01' ), -2 ),
306
			12 => array( QuantityValue::newFromNumber( '-117.3', '1', '-117.2', '-117.4' ), -1 ),
307
308
			20 => array( QuantityValue::newFromNumber( '+100', '1', '+100.01', '+99.97' ), -2 ),
309
			21 => array( QuantityValue::newFromNumber( '-0.002', '1', '-0.001', '-0.004' ), -3 ),
310
			22 => array( QuantityValue::newFromNumber( '-0.002', '1', '+0.001', '-0.06' ), -3 ),
311
			23 => array( QuantityValue::newFromNumber( '-21', '1', '+1.1', '-120' ), 1 ),
312
			24 => array( QuantityValue::newFromNumber( '-2', '1', '+1.1', '-120' ), 0 ),
313
			25 => array( QuantityValue::newFromNumber( '+1000', '1', '+1100', '+900.03' ), 1 ),
314
			26 => array( QuantityValue::newFromNumber( '+1000', '1', '+1100', '+900' ), 2 ),
315
		);
316
	}
317
318
	/**
319
	 * @dataProvider transformProvider
320
	 */
321
	public function testTransform( QuantityValue $quantity, $transformation, QuantityValue $expected ) {
322
		$args = func_get_args();
323
		$extraArgs = array_slice( $args, 3 );
324
325
		$call = array( $quantity, 'transform' );
326
		$callArgs = array_merge( array( 'x', $transformation ), $extraArgs );
327
		$actual = call_user_func_array( $call, $callArgs );
328
329
		$this->assertSame( 'x', $actual->getUnit() );
330
		$this->assertEquals( $expected->getAmount()->getValue(), $actual->getAmount()->getValue(), 'value' );
331
		$this->assertEquals( $expected->getUpperBound()->getValue(), $actual->getUpperBound()->getValue(), 'upper bound' );
332
		$this->assertEquals( $expected->getLowerBound()->getValue(), $actual->getLowerBound()->getValue(), 'lower bound' );
333
	}
334
335
	public function transformProvider() {
336
		$identity = function ( DecimalValue $value ) {
337
			return $value;
338
		};
339
340
		$square = function ( DecimalValue $value ) {
341
			$v = $value->getValueFloat();
342
			return new DecimalValue( $v * $v * $v );
343
		};
344
345
		$scale = function ( DecimalValue $value, $factor ) {
346
			return new DecimalValue( $value->getValueFloat() * $factor );
347
		};
348
349
		return array(
350
			0 => array(
351
				QuantityValue::newFromNumber( '+10', '1', '+11', '+9' ),
352
				$identity,
353
				QuantityValue::newFromNumber( '+10', '?', '+11', '+9' )
354
			),
355
			1 => array(
356
				QuantityValue::newFromNumber( '-0.5', '1', '-0.4', '-0.6' ),
357
				$identity,
358
				QuantityValue::newFromNumber( '-0.5', '?', '-0.4', '-0.6' )
359
			),
360
			2 => array(
361
				QuantityValue::newFromNumber( '+0', '1', '+1', '-1' ),
362
				$square,
363
				QuantityValue::newFromNumber( '+0', '?', '+1', '-1' )
364
			),
365
			3 => array(
366
				QuantityValue::newFromNumber( '+10', '1', '+11', '+9' ),
367
				$square,
368
				// note how rounding applies to bounds
369
				QuantityValue::newFromNumber( '+1000', '?', '+1300', '+700' )
370
			),
371
			4 => array(
372
				QuantityValue::newFromNumber( '+0.5', '1', '+0.6', '+0.4' ),
373
				$scale,
374
				QuantityValue::newFromNumber( '+0.25', '?', '+0.30', '+0.20' ),
375
				0.5
376
			),
377
378
			// note: absolutely exact values require conversion with infinite precision!
379
			10 => array(
380
				QuantityValue::newFromNumber( '+100', '1', '+100', '+100' ),
381
				$scale,
382
				QuantityValue::newFromNumber( '+12825', '?', '+12825', '+12825' ),
383
				128.25
384
			),
385
386
			11 => array(
387
				QuantityValue::newFromNumber( '+100', '1', '+110', '+90' ),
388
				$scale,
389
				QuantityValue::newFromNumber( '+330', '?', '+370', '+300' ),
390
				3.3333
391
			),
392
			12 => array(
393
				QuantityValue::newFromNumber( '+100', '1', '+100.1', '+99.9' ),
394
				$scale,
395
				QuantityValue::newFromNumber( '+333.3', '?', '+333.7', '+333.0' ),
396
				3.3333
397
			),
398
			13 => array(
399
				QuantityValue::newFromNumber( '+100', '1', '+100.01', '+99.99' ),
400
				$scale,
401
				QuantityValue::newFromNumber( '+333.33', '?', '+333.36', '+333.30' ),
402
				3.3333
403
			),
404
		);
405
	}
406
407
}
408