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