Completed
Push — master ( a25e2d...f3d5e6 )
by Daniel
24s
created

validArraySerializationProvider()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 29
Code Lines 21

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 1
Metric Value
c 2
b 1
f 1
dl 0
loc 29
rs 8.8571
cc 1
eloc 21
nc 1
nop 0
1
<?php
2
3
namespace DataValues\Tests;
4
5
use DataValues\DecimalValue;
6
use DataValues\QuantityValue;
7
use DataValues\UnboundedQuantityValue;
8
9
/**
10
 * @covers DataValues\UnboundedQuantityValue
11
 *
12
 * @group DataValue
13
 * @group DataValueExtensions
14
 *
15
 * @license GPL-2.0+
16
 * @author Daniel Kinzler
17
 */
18
class UnboundedQuantityValueTest extends DataValueTest {
19
20
	/**
21
	 * @see DataValueTest::getClass
22
	 *
23
	 * @return string
24
	 */
25
	public function getClass() {
26
		return 'DataValues\UnboundedQuantityValue';
27
	}
28
29
	public function validConstructorArgumentsProvider() {
30
		$argLists = array();
31
32
		$argLists[] = array( new DecimalValue( '+42' ), '1' );
33
		$argLists[] = array( new DecimalValue( '+0.01' ), '1' );
34
		$argLists[] = array( new DecimalValue( '-0.5' ), '1' );
35
36
		return $argLists;
37
	}
38
39
	public function invalidConstructorArgumentsProvider() {
40
		$argLists = array();
41
42
		$argLists[] = array( new DecimalValue( '+0' ), '' );
43
		$argLists[] = array( new DecimalValue( '+0' ), 1 );
44
45
		return $argLists;
46
	}
47
48
	/**
49
	 * @dataProvider instanceProvider
50
	 */
51
	public function testGetValue( UnboundedQuantityValue $quantity, array $arguments ) {
52
		$this->assertSame( $quantity, $quantity->getValue() );
53
	}
54
55
	/**
56
	 * @dataProvider instanceProvider
57
	 */
58
	public function testGetAmount( UnboundedQuantityValue $quantity, array $arguments ) {
59
		$this->assertSame( $arguments[0], $quantity->getAmount() );
60
	}
61
62
	/**
63
	 * @dataProvider instanceProvider
64
	 */
65
	public function testGetUnit( UnboundedQuantityValue $quantity, array $arguments ) {
66
		$this->assertSame( $arguments[1], $quantity->getUnit() );
67
	}
68
69
	/**
70
	 * @dataProvider newFromNumberProvider
71
	 */
72
	public function testNewFromNumber( $amount, $unit, UnboundedQuantityValue $expected ) {
73
		$quantity = UnboundedQuantityValue::newFromNumber( $amount, $unit );
74
75
		$this->assertEquals( $expected->getAmount()->getValue(), $quantity->getAmount()->getValue() );
76
	}
77
78
	public function newFromNumberProvider() {
79
		return array(
80
			array(
81
				42, '1',
82
				new UnboundedQuantityValue( new DecimalValue( '+42' ), '1' )
83
			),
84
			array(
85
				-0.05, '1',
86
				new UnboundedQuantityValue( new DecimalValue( '-0.05' ), '1' )
87
			),
88
			array(
89
				0, 'm',
90
				new UnboundedQuantityValue( new DecimalValue( '+0' ), 'm' )
91
			),
92
			array(
93
				'+23', '1',
94
				new UnboundedQuantityValue( new DecimalValue( '+23' ), '1' )
95
			),
96
			array(
97
				'+42', '1',
98
				new UnboundedQuantityValue( new DecimalValue( '+42' ), '1' )
99
			),
100
			array(
101
				'-0.05', 'm',
102
				new UnboundedQuantityValue( new DecimalValue( '-0.05' ), 'm' )
103
			),
104
			array(
105
				new DecimalValue( '+42' ), '1',
106
				new UnboundedQuantityValue( new DecimalValue( '+42' ), '1' )
107
			),
108
		);
109
	}
110
111
	/**
112
	 * @dataProvider validArraySerializationProvider
113
	 */
114
	public function testNewFromArray( $data, UnboundedQuantityValue $expected ) {
115
		$value = UnboundedQuantityValue::newFromArray( $data );
116
		$this->assertTrue( $expected->equals( $value ), $value . ' should equal ' . $expected );
117
	}
118
119
	public function validArraySerializationProvider() {
120
		return array(
121
			'unbounded' => array(
122
				array(
123
					'amount' => '+2',
124
					'unit' => '1',
125
				),
126
				UnboundedQuantityValue::newFromNumber( '+2', '1' )
127
			),
128
			'unbounded with existing array keys' => array(
129
				array(
130
					'amount' => '+2',
131
					'unit' => '1',
132
					'upperBound' => null,
133
					'lowerBound' => null,
134
				),
135
				UnboundedQuantityValue::newFromNumber( '+2', '1' )
136
			),
137
			'with-extra' => array(
138
				array(
139
					'amount' => '+2',
140
					'unit' => '1',
141
					'upperBound' => '+2.5',
142
					'lowerBound' => '+1.5',
143
				),
144
				QuantityValue::newFromNumber( '+2', '1', '+2.5', '+1.5' )
145
			),
146
		);
147
	}
148
149
	/**
150
	 * @dataProvider invalidArraySerializationProvider
151
	 */
152
	public function testNewFromArray_failure( $data ) {
153
		$this->setExpectedException( 'DataValues\IllegalValueException' );
154
		UnboundedQuantityValue::newFromArray( $data );
155
	}
156
157
	public function invalidArraySerializationProvider() {
158
		return array(
159
			'no-amount' => array(
160
				array(
161
					'unit' => '1',
162
				)
163
			),
164
			'no-unit' => array(
165
				array(
166
					'amount' => '+2',
167
				)
168
			),
169
			'no-upperBound' => array(
170
				array(
171
					'amount' => '+2',
172
					'unit' => '1',
173
					'lowerBound' => '+1.5',
174
				)
175
			),
176
			'no-lowerBound' => array(
177
				array(
178
					'amount' => '+2',
179
					'unit' => '1',
180
					'upperBound' => '+2.5',
181
				)
182
			),
183
			'bad-amount' => array(
184
				array(
185
					'amount' => 'x',
186
					'unit' => '1',
187
				)
188
			),
189
			'bad-upperBound' => array(
190
				array(
191
					'amount' => '+2',
192
					'unit' => '1',
193
					'upperBound' => 'x',
194
					'lowerBound' => '+1.5',
195
				)
196
			),
197
			'bad-lowerBound' => array(
198
				array(
199
					'amount' => '+2',
200
					'unit' => '1',
201
					'upperBound' => '+2.5',
202
					'lowerBound' => 'x',
203
				)
204
			),
205
		);
206
	}
207
208
	/**
209
	 * @see https://phabricator.wikimedia.org/T110728
210
	 * @see http://www.regular-expressions.info/anchors.html#realend
211
	 */
212
	public function testTrailingNewlineRobustness() {
213
		$value = UnboundedQuantityValue::newFromArray( array(
214
			'amount' => "-0.0\n",
215
			'unit' => "1\n",
216
		) );
217
218
		$this->assertSame( array(
219
			'amount' => '+0.0',
220
			'unit' => "1\n",
221
		), $value->getArrayValue() );
222
	}
223
224
	/**
225
	 * @dataProvider instanceProvider
226
	 */
227
	public function testGetSortKey( UnboundedQuantityValue $quantity ) {
228
		$this->assertSame( $quantity->getAmount()->getValueFloat(), $quantity->getSortKey() );
229
	}
230
231
	/**
232
	 * @dataProvider transformProvider
233
	 */
234
	public function testTransform( UnboundedQuantityValue $quantity, $transformation, UnboundedQuantityValue $expected ) {
235
		$args = func_get_args();
236
		$extraArgs = array_slice( $args, 3 );
237
238
		$call = array( $quantity, 'transform' );
239
		$callArgs = array_merge( array( 'x', $transformation ), $extraArgs );
240
		$actual = call_user_func_array( $call, $callArgs );
241
242
		$this->assertSame( 'x', $actual->getUnit() );
243
		$this->assertEquals( $expected->getAmount()->getValue(), $actual->getAmount()->getValue(), 'value' );
244
	}
245
246
	public function transformProvider() {
247
		$identity = function ( DecimalValue $value ) {
248
			return $value;
249
		};
250
251
		$square = function ( DecimalValue $value ) {
252
			$v = $value->getValueFloat();
253
			return new DecimalValue( $v * $v * $v );
254
		};
255
256
		$scale = function ( DecimalValue $value, $factor ) {
257
			return new DecimalValue( $value->getValueFloat() * $factor );
258
		};
259
260
		return array(
261
			0 => array(
262
				UnboundedQuantityValue::newFromNumber( '+10', '1' ),
263
				$identity,
264
				UnboundedQuantityValue::newFromNumber( '+10', '?' )
265
			),
266
			1 => array(
267
				UnboundedQuantityValue::newFromNumber( '-0.5', '1' ),
268
				$identity,
269
				UnboundedQuantityValue::newFromNumber( '-0.5', '?' )
270
			),
271
			2 => array(
272
				UnboundedQuantityValue::newFromNumber( '+0', '1' ),
273
				$square,
274
				UnboundedQuantityValue::newFromNumber( '+0', '?' )
275
			),
276
			3 => array(
277
				UnboundedQuantityValue::newFromNumber( '+10', '1' ),
278
				$square,
279
				UnboundedQuantityValue::newFromNumber( '+1000', '?' )
280
			),
281
			4 => array(
282
				UnboundedQuantityValue::newFromNumber( '+0.5', '1' ),
283
				$scale,
284
				UnboundedQuantityValue::newFromNumber( '+0.25', '?' ),
285
				0.5
286
			),
287
288
			// note: absolutely exact values require conversion with infinite precision!
289
			10 => array(
290
				UnboundedQuantityValue::newFromNumber( '+100', '1' ),
291
				$scale,
292
				UnboundedQuantityValue::newFromNumber( '+12825', '?' ),
293
				128.25
294
			),
295
			13 => array(
296
				UnboundedQuantityValue::newFromNumber( '+100', '1' ),
297
				$scale,
298
				UnboundedQuantityValue::newFromNumber( '+333.33', '?' ),
299
				3.3333
300
			),
301
		);
302
	}
303
304
}
305