Completed
Push — master ( 5e016a...19cfc9 )
by Daniel
22s
created

invalidConstructorArgumentsProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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