Completed
Pull Request — master (#66)
by Daniel
05:21 queued 02:25
created

testTrailingNewlineRobustness()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 11
rs 9.4285
cc 1
eloc 8
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
	public function newFromNumberProvider() {
71
		return array(
72
			array(
73
				42, '1',
74
				new UnboundedQuantityValue( new DecimalValue( '+42' ), '1' )
75
			),
76
			array(
77
				-0.05, '1',
78
				new UnboundedQuantityValue( new DecimalValue( '-0.05' ), '1' )
79
			),
80
			array(
81
				0, 'm',
82
				new UnboundedQuantityValue( new DecimalValue( '+0' ), 'm' )
83
			),
84
			array(
85
				'+23', '1',
86
				new UnboundedQuantityValue( new DecimalValue( '+23' ), '1' )
87
			),
88
			array(
89
				'+42', '1',
90
				new UnboundedQuantityValue( new DecimalValue( '+42' ), '1' )
91
			),
92
			array(
93
				'-0.05', 'm',
94
				new UnboundedQuantityValue( new DecimalValue( '-0.05' ), 'm' )
95
			),
96
			array(
97
				new DecimalValue( '+42' ), '1',
98
				new UnboundedQuantityValue( new DecimalValue( '+42' ), '1' )
99
			),
100
		);
101
	}
102
103
	/**
104
	 * @see https://phabricator.wikimedia.org/T110728
105
	 * @see http://www.regular-expressions.info/anchors.html#realend
106
	 */
107
	public function testTrailingNewlineRobustness() {
108
		$value = UnboundedQuantityValue::newFromArray( array(
109
			'amount' => "-0.0\n",
110
			'unit' => "1\n",
111
		) );
112
113
		$this->assertSame( array(
114
			'amount' => '+0.0',
115
			'unit' => "1\n",
116
		), $value->getArrayValue() );
117
	}
118
119
	/**
120
	 * @dataProvider instanceProvider
121
	 */
122
	public function testGetSortKey( UnboundedQuantityValue $quantity ) {
123
		$this->assertEquals( $quantity->getAmount()->getValueFloat(), $quantity->getSortKey() );
124
	}
125
126
	/**
127
	 * @dataProvider transformProvider
128
	 */
129
	public function testTransform( UnboundedQuantityValue $quantity, $transformation, UnboundedQuantityValue $expected ) {
130
		$args = func_get_args();
131
		$extraArgs = array_slice( $args, 3 );
132
133
		$call = array( $quantity, 'transform' );
134
		$callArgs = array_merge( array( 'x', $transformation ), $extraArgs );
135
		$actual = call_user_func_array( $call, $callArgs );
136
137
		$this->assertEquals( 'x', $actual->getUnit() );
138
		$this->assertEquals( $expected->getAmount()->getValue(), $actual->getAmount()->getValue(), 'value' );
139
	}
140
141
	public function transformProvider() {
142
		$identity = function ( DecimalValue $value ) {
143
			return $value;
144
		};
145
146
		$square = function ( DecimalValue $value ) {
147
			$v = $value->getValueFloat();
148
			return new DecimalValue( $v * $v * $v );
149
		};
150
151
		$scale = function ( DecimalValue $value, $factor ) {
152
			return new DecimalValue( $value->getValueFloat() * $factor );
153
		};
154
155
		return array(
156
			 0 => array( UnboundedQuantityValue::newFromNumber( '+10', '1' ), $identity, UnboundedQuantityValue::newFromNumber( '+10', '?' ) ),
157
			 1 => array( UnboundedQuantityValue::newFromNumber( '-0.5', '1' ), $identity, UnboundedQuantityValue::newFromNumber( '-0.5', '?' ) ),
158
			 2 => array( UnboundedQuantityValue::newFromNumber( '+0', '1' ), $square,   UnboundedQuantityValue::newFromNumber( '+0', '?' ) ),
159
			 3 => array( UnboundedQuantityValue::newFromNumber( '+10', '1' ), $square,   UnboundedQuantityValue::newFromNumber( '+1000', '?' ) ), // note how rounding applies to bounds
160
			 4 => array( UnboundedQuantityValue::newFromNumber( '+0.5', '1' ), $scale,    UnboundedQuantityValue::newFromNumber( '+0.25', '?' ), 0.5 ),
161
162
			// note: absolutely exact values require conversion with infinite precision!
163
			10 => array( UnboundedQuantityValue::newFromNumber( '+100', '1' ), $scale, UnboundedQuantityValue::newFromNumber( '+12825.0', '?' ), 128.25 ),
164
			13 => array( UnboundedQuantityValue::newFromNumber( '+100', '1' ), $scale, UnboundedQuantityValue::newFromNumber( '+333.33', '?' ), 3.3333 ),
165
		);
166
	}
167
168
	public function provideNewFromArray() {
169
		return [
170
			'unbounded' => [
171
				[
172
					'amount' => '+2',
173
					'unit' => '1',
174
				],
175
				UnboundedQuantityValue::newFromNumber( '+2', '1' )
176
			],
177
			'with-extra' => [
178
				[
179
					'amount' => '+2',
180
					'unit' => '1',
181
					'upperBound' => '+2.5',
182
					'lowerBound' => '+1.5',
183
				],
184
				UnboundedQuantityValue::newFromNumber( '+2', '1' )
185
			],
186
		];
187
	}
188
189
	/**
190
	 * @dataProvider provideNewFromArray
191
	 */
192
	public function testNewFromArray( $data, DataValue $expected ) {
193
		$value = UnboundedQuantityValue::newFromArray( $data );
194
		$this->assertTrue( $expected->equals( $value ), $value . ' should equal ' . $expected );
195
	}
196
197
	public function provideNewFromArray_failure() {
198
		return [
199
			'no-amount' => [
200
				[
201
					'unit' => "1",
202
				]
203
			],
204
			'no-unit' => [
205
				[
206
					'amount' => '+2',
207
				]
208
			],
209
			'bad-amount' => [
210
				[
211
					'amount' => 'x',
212
					'unit' => "1",
213
				]
214
			],
215
		];
216
	}
217
218
	/**
219
	 * @dataProvider provideNewFromArray_failure
220
	 */
221
	public function testNewFromArray_failure( $data ) {
222
		$this->setExpectedException( IllegalValueException::class );
223
		UnboundedQuantityValue::newFromArray( $data );
224
	}
225
226
}
227