Passed
Push — master ( 050c5b...b0f6e4 )
by Marius
02:52
created

DecimalValueTest::testFloatInputs()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 5
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 2
1
<?php
2
3
namespace DataValues\Tests;
4
5
use DataValues\DecimalValue;
6
7
/**
8
 * @covers DataValues\DecimalValue
9
 *
10
 * @group DataValue
11
 * @group DataValueExtensions
12
 *
13
 * @license GPL-2.0+
14
 * @author Daniel Kinzler
15
 */
16
class DecimalValueTest extends DataValueTest {
17
18
	/**
19
	 * @see DataValueTest::getClass
20
	 *
21
	 * @return string
22
	 */
23
	public function getClass() {
24
		return DecimalValue::class;
25
	}
26
27
	public function validConstructorArgumentsProvider() {
28
		$argLists = [];
29
30
		$argLists[] = [ 42 ];
31
		$argLists[] = [ -42 ];
32
		$argLists[] = [ '-42' ];
33
		$argLists[] = [ 4.2 ];
34
		$argLists[] = [ -4.2 ];
35
		$argLists[] = [ '+4.2' ];
36
		$argLists[] = [ " +4.2\n" ];
37
		$argLists[] = [ 0 ];
38
		$argLists[] = [ 0.2 ];
39
		$argLists[] = [ '-0.42' ];
40
		$argLists[] = [ '-0.0' ];
41
		$argLists[] = [ '-0' ];
42
		$argLists[] = [ '+0' ];
43
		$argLists[] = [ '+0.0' ];
44
		$argLists[] = [ '+0.000' ];
45
		$argLists[] = [ '+1.' . str_repeat( '0', 124 ) ];
46
		$argLists[] = [ '+1.0' . str_repeat( ' ', 124 ) ];
47
		$argLists[] = [ '4.2' ];
48
		$argLists[] = [ " 4.2\n" ];
49
50
		return $argLists;
51
	}
52
53
	public function invalidConstructorArgumentsProvider() {
54
		$argLists = [];
55
56
		$argLists[] = [ 'foo' ];
57
		$argLists[] = [ '' ];
58
		$argLists[] = [ '++4.2' ];
59
		$argLists[] = [ '--4.2' ];
60
		$argLists[] = [ '-+4.2' ];
61
		$argLists[] = [ '+-4.2' ];
62
		$argLists[] = [ '+/-0' ];
63
		$argLists[] = [ '-.42' ];
64
		$argLists[] = [ '+.42' ];
65
		$argLists[] = [ '.42' ];
66
		$argLists[] = [ '.0' ];
67
		$argLists[] = [ '-00' ];
68
		$argLists[] = [ '−1' ];
69
		$argLists[] = [ '+01.2' ];
70
		$argLists[] = [ 'x2' ];
71
		$argLists[] = [ '2x' ];
72
		$argLists[] = [ '+0100' ];
73
		$argLists[] = [ false ];
74
		$argLists[] = [ true ];
75
		$argLists[] = [ null ];
76
		$argLists[] = [ '0x20' ];
77
		$argLists[] = [ '+1.' . str_repeat( '0', 125 ) ];
78
79
		return $argLists;
80
	}
81
82
	/**
83
	 * @see https://phabricator.wikimedia.org/T110728
84
	 * @see http://www.regular-expressions.info/anchors.html#realend
85
	 */
86
	public function testTrailingNewlineRobustness() {
87
		$value = DecimalValue::newFromArray( "-0.0\n" );
0 ignored issues
show
Deprecated Code introduced by
The method DataValues\DecimalValue::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.

Loading history...
88
89
		$this->assertTrue( $value->isZero() );
90
		$this->assertSame( 'C:23:"DataValues\DecimalValue":11:{s:4:"+0.0";}', serialize( $value ) );
91
		$this->assertSame( '+0.0', $value->getValue(), 'getValue' );
92
		$this->assertSame( '+0.0', $value->getArrayValue(), 'getArrayValue' );
93
		$this->assertSame( '+0.0', $value->__toString(), '__toString' );
94
		$this->assertSame( '0', $value->getFractionalPart(), 'getFractionalPart' );
95
	}
96
97
	/**
98
	 * @dataProvider provideFloats
99
	 */
100
	public function testFloatInputs( $float, $expectedPrefix ) {
101
		$value = DecimalValue::newFromArray( $float );
0 ignored issues
show
Deprecated Code introduced by
The method DataValues\DecimalValue::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.

Loading history...
102
103
		$this->assertStringStartsWith( $expectedPrefix, $value->getValue(), 'getValue' );
104
	}
105
106
	public function provideFloats() {
107
		return [
108
			[ 0.000000002, '+0.000000002' ],
109
			[ 0.000003, '+0.000003' ],
110
			[ 0.9, '+0.9' ],
111
			[ 1.2, '+1.2' ],
112
			[ 1.5, '+1.5' ],
113
			[ 123E-1, '+12.3' ],
114
			[ 123E+1, '+1230' ],
115
			[ 1234567890123456, '+1234567890123' ],
116
			[ 1234567890123456789, '+1234567890123' ],
117
		];
118
	}
119
120
	/**
121
	 * @dataProvider compareProvider
122
	 */
123
	public function testCompare( DecimalValue $a, DecimalValue $b, $expected ) {
124
		$actual = $a->compare( $b );
0 ignored issues
show
Documentation introduced by
$b is of type object<DataValues\DecimalValue>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
125
		$this->assertSame( $expected, $actual );
126
127
		$actual = $b->compare( $a );
0 ignored issues
show
Documentation introduced by
$a is of type object<DataValues\DecimalValue>, but the function expects a object<self>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
128
		$this->assertSame( -$expected, $actual );
129
	}
130
131
	public function compareProvider() {
132
		return [
133
			'zero/equal' => [ new DecimalValue( 0 ), new DecimalValue( 0 ), 0 ],
134
			'zero-signs/equal' => [ new DecimalValue( '+0' ), new DecimalValue( '-0' ), 0 ],
135
			'zero-digits/equal' => [ new DecimalValue( '+0' ), new DecimalValue( '+0.000' ), 0 ],
136
			'digits/equal' => [ new DecimalValue( '+2.2' ), new DecimalValue( '+2.2000' ), 0 ],
137
			'conversion/equal' => [ new DecimalValue( 2.5 ), new DecimalValue( '+2.50' ), 0 ],
138
			'negative/equal' => [ new DecimalValue( '-1.33' ), new DecimalValue( '-1.33' ), 0 ],
139
140
			'simple/smaller' => [ new DecimalValue( '+1' ), new DecimalValue( '+2' ), -1 ],
141
			'simple/greater' => [ new DecimalValue( '+2' ), new DecimalValue( '+1' ), 1 ],
142
			'negative/greater' => [ new DecimalValue( '-1' ), new DecimalValue( '-2' ), 1 ],
143
			'negative/smaller' => [ new DecimalValue( '-2' ), new DecimalValue( '-1' ), -1 ],
144
			'negative-small/greater' => [ new DecimalValue( '-0.5' ), new DecimalValue( '-0.7' ), 1 ],
145
			'negative-small/smaller' => [ new DecimalValue( '-0.7' ), new DecimalValue( '-0.5' ), -1 ],
146
147
			'digits/greater' => [ new DecimalValue( '+11' ), new DecimalValue( '+8' ), 1 ],
148
			'digits-sub/greater' => [ new DecimalValue( '+11' ), new DecimalValue( '+8.0' ), 1 ],
149
			'negative-digits/greater' => [ new DecimalValue( '-11' ), new DecimalValue( '-80' ), 1 ],
150
			'small/greater' => [ new DecimalValue( '+0.050' ), new DecimalValue( '+0.005' ), 1 ],
151
152
			'signs/greater' => [ new DecimalValue( '+1' ), new DecimalValue( '-8' ), 1 ],
153
			'signs/less' => [ new DecimalValue( '-8' ), new DecimalValue( '+1' ), -1 ],
154
155
			'with-and-without-point' => [ new DecimalValue( '+100' ), new DecimalValue( '+100.01' ), -1 ],
156
		];
157
	}
158
159
	/**
160
	 * @dataProvider getSignProvider
161
	 */
162
	public function testGetSign( DecimalValue $value, $expected ) {
163
		$actual = $value->getSign();
164
		$this->assertSame( $expected, $actual );
165
	}
166
167
	public function getSignProvider() {
168
		return [
169
			'zero is positive' => [ new DecimalValue( 0 ), '+' ],
170
			'zero is always positive' => [ new DecimalValue( '-0' ), '+' ],
171
			'zero is ALWAYS positive' => [ new DecimalValue( '-0.00' ), '+' ],
172
			'+1 is positive' => [ new DecimalValue( '+1' ), '+' ],
173
			'-1 is negative' => [ new DecimalValue( '-1' ), '-' ],
174
			'+0.01 is positive' => [ new DecimalValue( '+0.01' ), '+' ],
175
			'-0.01 is negative' => [ new DecimalValue( '-0.01' ), '-' ],
176
		];
177
	}
178
179
	/**
180
	 * @dataProvider getValueProvider
181
	 */
182
	public function testGetValue( DecimalValue $value, $expected ) {
183
		$actual = $value->getValue();
184
		$this->assertSame( $expected, $actual );
185
	}
186
187
	public function getValueProvider() {
188
		$argLists = [];
189
190
		$argLists[] = [ new DecimalValue( 42 ), '+42' ];
191
		$argLists[] = [ new DecimalValue( -42 ), '-42' ];
192
		$argLists[] = [ new DecimalValue( -42.0 ), '-42' ];
193
		$argLists[] = [ new DecimalValue( '-42' ), '-42' ];
194
		$argLists[] = [ new DecimalValue( 4.5 ), '+4.5' ];
195
		$argLists[] = [ new DecimalValue( -4.5 ), '-4.5' ];
196
		$argLists[] = [ new DecimalValue( '+4.2' ), '+4.2' ];
197
		$argLists[] = [ new DecimalValue( 0 ), '+0' ];
198
		$argLists[] = [ new DecimalValue( 0.0 ), '+0' ];
199
		$argLists[] = [ new DecimalValue( 1.0 ), '+1' ];
200
		$argLists[] = [ new DecimalValue( 0.5 ), '+0.5' ];
201
		$argLists[] = [ new DecimalValue( '-0.42' ), '-0.42' ];
202
		$argLists[] = [ new DecimalValue( '-0.0' ), '+0.0' ];
203
		$argLists[] = [ new DecimalValue( '-0' ), '+0' ];
204
		$argLists[] = [ new DecimalValue( '+0.0' ), '+0.0' ];
205
		$argLists[] = [ new DecimalValue( '+0' ), '+0' ];
206
		$argLists[] = [ new DecimalValue( 2147483649 ), '+2147483649' ];
207
		$argLists[] = [ new DecimalValue( 1000000000000000 ), '+1000000000000000' ];
208
		$argLists[] = [
209
			new DecimalValue( 1 + 1e-12 / 3 ),
210
			'+1.0000000000003'
211
		];
212
		$argLists[] = [
213
			new DecimalValue( 1 + 1e-14 / 3 ),
214
			'+1'
215
		];
216
217
		return $argLists;
218
	}
219
220
	/**
221
	 * @dataProvider getValueFloatProvider
222
	 */
223
	public function testGetValueFloat( DecimalValue $value, $expected ) {
224
		$actual = $value->getValueFloat();
225
		$this->assertSame( $expected, $actual );
226
	}
227
228
	public function getValueFloatProvider() {
229
		$argLists = [];
230
231
		$argLists[] = [ new DecimalValue( 42 ), 42.0 ];
232
		$argLists[] = [ new DecimalValue( -42 ), -42.0 ];
233
		$argLists[] = [ new DecimalValue( '-42' ), -42.0 ];
234
		$argLists[] = [ new DecimalValue( 4.5 ), 4.5 ];
235
		$argLists[] = [ new DecimalValue( -4.5 ), -4.5 ];
236
		$argLists[] = [ new DecimalValue( '+4.2' ), 4.2 ];
237
		$argLists[] = [ new DecimalValue( 0 ), 0.0 ];
238
		$argLists[] = [ new DecimalValue( 0.5 ), 0.5 ];
239
		$argLists[] = [ new DecimalValue( '-0.42' ), -0.42 ];
240
		$argLists[] = [ new DecimalValue( '-0.0' ), 0.0 ];
241
		$argLists[] = [ new DecimalValue( '-0' ), 0.0 ];
242
		$argLists[] = [ new DecimalValue( '+0.0' ), 0.0 ];
243
		$argLists[] = [ new DecimalValue( '+0' ), 0.0 ];
244
245
		return $argLists;
246
	}
247
248
	/**
249
	 * @dataProvider getGetIntegerPartProvider
250
	 */
251
	public function testGetIntegerPart( DecimalValue $value, $expected ) {
252
		$actual = $value->getIntegerPart();
253
		$this->assertSame( $expected, $actual );
254
	}
255
256
	public function getGetIntegerPartProvider() {
257
		return [
258
			[ new DecimalValue( '+0' ), '0' ],
259
			[ new DecimalValue( '-0.0' ), '0' ],
260
			[ new DecimalValue( '+10' ), '10' ],
261
			[ new DecimalValue( '-10' ), '10' ],
262
			[ new DecimalValue( '+10.663' ), '10' ],
263
			[ new DecimalValue( '-10.001' ), '10' ],
264
			[ new DecimalValue( '+0.01' ), '0' ],
265
		];
266
	}
267
268
	/**
269
	 * @dataProvider getGetIntegerPartProvider
270
	 */
271
	public function testGetFractionalPart( DecimalValue $value, $expected ) {
272
		$actual = $value->getIntegerPart();
273
		$this->assertSame( $expected, $actual );
274
	}
275
276
	public function getGetFractionalPartProvider() {
277
		return [
278
			[ new DecimalValue( '+0' ), '' ],
279
			[ new DecimalValue( '-0.0' ), '0' ],
280
			[ new DecimalValue( '+10' ), '' ],
281
			[ new DecimalValue( '+10.663' ), '663' ],
282
			[ new DecimalValue( '-10.001' ), '001' ],
283
			[ new DecimalValue( '+0.01' ), '01' ],
284
		];
285
	}
286
287
	/**
288
	 * @dataProvider computeComplementProvider
289
	 */
290
	public function testComputeComplement( DecimalValue $value, $expected ) {
291
		$complement = $value->computeComplement();
292
		$this->assertSame( $expected, $complement->getValue() );
293
294
		$actual = $complement->computeComplement();
295
		$this->assertSame( $value->getValue(), $actual->getValue() );
296
	}
297
298
	public function computeComplementProvider() {
299
		return [
300
			[ new DecimalValue( '+0' ), '+0' ],
301
			[ new DecimalValue( '+0.00' ), '+0.00' ],
302
			[ new DecimalValue( '+1' ), '-1' ],
303
			[ new DecimalValue( '+100.663' ), '-100.663' ],
304
			[ new DecimalValue( '-0.001' ), '+0.001' ],
305
		];
306
	}
307
308
	/**
309
	 * @dataProvider computeComputeAbsolute
310
	 */
311
	public function testComputeAbsolute( DecimalValue $value, $expected ) {
312
		$absolute = $value->computeAbsolute();
313
		$this->assertSame( $expected, $absolute->getValue() );
314
315
		$actual = $absolute->computeAbsolute();
316
		$this->assertSame( $absolute->getValue(), $actual->getValue() );
317
	}
318
319
	public function computeComputeAbsolute() {
320
		return [
321
			[ new DecimalValue( '+0' ), '+0' ],
322
			[ new DecimalValue( '+1' ), '+1' ],
323
			[ new DecimalValue( '-1' ), '+1' ],
324
			[ new DecimalValue( '+100.663' ), '+100.663' ],
325
			[ new DecimalValue( '-100.663' ), '+100.663' ],
326
			[ new DecimalValue( '+0.001' ), '+0.001' ],
327
			[ new DecimalValue( '-0.001' ), '+0.001' ],
328
		];
329
	}
330
331
	/**
332
	 * @dataProvider isZeroProvider
333
	 */
334
	public function testIsZero( DecimalValue $value, $expected ) {
335
		$actual = $value->isZero();
336
		$this->assertSame( $expected, $actual );
337
	}
338
339
	public function isZeroProvider() {
340
		return [
341
			[ new DecimalValue( '+0' ), true ],
342
			[ new DecimalValue( '-0.00' ), true ],
343
344
			[ new DecimalValue( '+1' ),       false ],
345
			[ new DecimalValue( '+100.663' ), false ],
346
			[ new DecimalValue( '-0.001' ),   false ],
347
		];
348
	}
349
350
	/**
351
	 * @dataProvider provideGetTrim
352
	 */
353
	public function testGetTrim( DecimalValue $value, DecimalValue $expected ) {
354
		$actual = $value->getTrimmed();
355
		$this->assertSame( $expected->getValue(), $actual->getValue() );
356
	}
357
358
	public function provideGetTrim() {
359
		return [
360
			[ new DecimalValue( '+8' ),     new DecimalValue( '+8' ) ],
361
			[ new DecimalValue( '+80' ),    new DecimalValue( '+80' ) ],
362
			[ new DecimalValue( '+800' ),   new DecimalValue( '+800' ) ],
363
			[ new DecimalValue( '+0' ),     new DecimalValue( '+0' ) ],
364
			[ new DecimalValue( '+0.0' ),   new DecimalValue( '+0' ) ],
365
			[ new DecimalValue( '+10.00' ), new DecimalValue( '+10' ) ],
366
			[ new DecimalValue( '-0.1' ),   new DecimalValue( '-0.1' ) ],
367
			[ new DecimalValue( '-0.10' ),  new DecimalValue( '-0.1' ) ],
368
			[ new DecimalValue( '-0.010' ), new DecimalValue( '-0.01' ) ],
369
			[ new DecimalValue( '-0.001' ), new DecimalValue( '-0.001' ) ],
370
		];
371
	}
372
373
}
374