DecimalParserTest::testApplyDecimalExponent()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 3
1
<?php
2
3
namespace ValueParsers\Test;
4
5
use DataValues\DecimalValue;
6
use ValueParsers\DecimalParser;
7
use ValueParsers\NumberUnlocalizer;
8
9
/**
10
 * @covers ValueParsers\DecimalParser
11
 *
12
 * @group DataValue
13
 * @group DataValueExtensions
14
 *
15
 * @license GPL-2.0-or-later
16
 * @author Daniel Kinzler
17
 */
18
class DecimalParserTest extends ValueParserTestCase {
19
20
	/**
21
	 * @return DecimalParser
22
	 */
23
	protected function getInstance() {
24
		$unlocalizer = $this->createMock( NumberUnlocalizer::class );
25
		$unlocalizer->method( 'unlocalizeNumber' )
0 ignored issues
show
Bug introduced by
The method method() does not seem to exist on object<PHPUnit\Framework\MockObject\MockObject>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
26
			->will( $this->returnArgument( 0 ) );
27
28
		return new DecimalParser( null, $unlocalizer );
0 ignored issues
show
Documentation introduced by
$unlocalizer is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a null|object<ValueParsers\NumberUnlocalizer>.

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...
29
	}
30
31
	/**
32
	 * @see ValueParserTestCase::validInputProvider
33
	 */
34
	public function validInputProvider() {
35
		$argLists = [];
36
37
		$valid = [
38
			'0' => 0,
39
			'-0' => 0,
40
			'-00.00' => '-0.00',
41
			'+00.00' => '+0.00',
42
			'0001' => 1,
43
			'+42' => 42,
44
			'+01' => 01,
45
			'9001' => 9001,
46
			'-1' => -1,
47
			'-42' => -42,
48
			'.5' => 0.5,
49
			'-.125' => -0.125,
50
			'3.' => 3,
51
			',3,' => 3,
52
			'2.125' => 2.125,
53
			'2.1250' => '+2.1250',
54
			'2.1250e0' => '+2.1250',
55
			'2.1250e3' => '+2125.0',
56
			'2.1250e+3' => '+2125.0',
57
			'2.1250e-2' => '+0.021250',
58
			'123e+3' => '+123000',
59
			'123e-2' => '+1.23',
60
			'-123e-5' => '-0.00123',
61
			' 5 ' => 5,
62
			'100,000' => 100000,
63
			'100 000' => 100000,
64
			'100\'000' => 100000,
65
66
			// U+000C (form feed)
67
			"5\f" => 5,
68
			// U+00A0 (non-break space)
69
			"5\xC2\xA0200" => 5200,
70
			// U+202F (narrow no-break space)
71
			"5\xE2\x80\xAF300" => 5300,
72
		];
73
74
		foreach ( $valid as $value => $expected ) {
75
			// Because PHP turns them into ints using black magic
76
			$value = (string)$value;
77
78
			$expected = new DecimalValue( $expected );
79
			$argLists[] = [ $value, $expected ];
80
		}
81
82
		return $argLists;
83
	}
84
85
	/**
86
	 * @see ValueParserTestCase::invalidInputProvider
87
	 */
88
	public function invalidInputProvider() {
89
		$argLists = [
90
			[ true ],
91
			[ false ],
92
			[ null ],
93
			[ 4.2 ],
94
			[ [] ],
95
			[ 42 ]
96
		];
97
98
		$invalid = [
99
			'foo',
100
			'',
101
			'--1',
102
			'1-',
103
			'one',
104
			'0x20',
105
			'1+1',
106
			'1-1',
107
			'1.2.3',
108
		];
109
110
		foreach ( $invalid as $value ) {
111
			$argLists[] = [ $value ];
112
		}
113
114
		return $argLists;
115
	}
116
117
	public function testUnlocalization() {
118
		$unlocalizer = $this->createMock( NumberUnlocalizer::class );
119
120
		$unlocalizer->expects( $this->once() )
121
			->method( 'unlocalizeNumber' )
122
			->will( $this->returnCallback( function ( $number ) {
123
				return str_replace( '#', '', $number );
124
			} ) );
125
126
		$unlocalizer->expects( $this->never() )
127
			->method( 'getNumberRegex' );
128
129
		$unlocalizer->expects( $this->never() )
130
			->method( 'getUnitRegex' );
131
132
		$parser = new DecimalParser( null, $unlocalizer );
0 ignored issues
show
Documentation introduced by
$unlocalizer is of type object<PHPUnit\Framework\MockObject\MockObject>, but the function expects a null|object<ValueParsers\NumberUnlocalizer>.

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...
133
134
		$input = '###20#000#000###';
135
		/** @var DecimalValue $value */
136
		$value = $parser->parse( $input );
137
138
		$this->assertSame( '+20000000', $value->getValue() );
139
	}
140
141
	public function splitDecimalExponentProvider() {
142
		return [
143
			'trailing newline' => [ "1.2E3\n", '1.2', 3 ],
144
			'whitespace' => [ ' 1.2E3 ', ' 1.2E3 ', 0 ],
145
			'no exponent' => [ '1.2', '1.2', 0 ],
146
			'exponent' => [ '1.2E3', '1.2', 3 ],
147
			'negative exponent' => [ '+1.2e-2', '+1.2', -2 ],
148
			'positive exponent' => [ '-12e+3', '-12', 3 ],
149
			'leading zero' => [ '12e+09', '12', 9 ],
150
			'trailing decimal point' => [ '12.e+3', '12.', 3 ],
151
			'leading decimal point' => [ '.12e+3', '.12', 3 ],
152
			'space' => [ '12 e+3', '12 ', 3 ],
153
			'x10 syntax' => [ '12x10^3', '12', 3 ],
154
			'comma' => [ '12e3,4', '12', 34 ],
155
		];
156
	}
157
158
	/**
159
	 * @dataProvider splitDecimalExponentProvider
160
	 */
161
	public function testSplitDecimalExponent( $valueString, $expectedDecimal, $expectedExponent ) {
162
		$parser = new DecimalParser();
163
		list( $decimal, $exponent ) = $parser->splitDecimalExponent( $valueString );
164
165
		$this->assertSame( $expectedDecimal, $decimal );
166
		$this->assertSame( $expectedExponent, $exponent );
167
	}
168
169
	public function applyDecimalExponentProvider() {
170
		return [
171
			'no exponent' => [ new DecimalValue( '+1.2' ), 0, new DecimalValue( '+1.2' ) ],
172
			'negative exponent' => [ new DecimalValue( '-1.2' ), -2, new DecimalValue( '-0.012' ) ],
173
			'positive exponent' => [ new DecimalValue( '-12' ), 3, new DecimalValue( '-12000' ) ],
174
		];
175
	}
176
177
	/**
178
	 * @dataProvider applyDecimalExponentProvider
179
	 */
180
	public function testApplyDecimalExponent( DecimalValue $decimal, $exponent, DecimalValue $expectedDecimal ) {
181
		$parser = new DecimalParser();
182
		$actualDecimal = $parser->applyDecimalExponent( $decimal, $exponent );
183
184
		$this->assertSame( $expectedDecimal->getValue(), $actualDecimal->getValue() );
185
	}
186
187
}
188