DecimalParserTest   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 165
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3

Importance

Changes 0
Metric Value
wmc 10
lcom 1
cbo 3
dl 0
loc 165
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A getInstance() 0 7 1
A validInputProvider() 0 50 2
A invalidInputProvider() 0 21 2
A testUnlocalization() 0 23 1
A splitDecimalExponentProvider() 0 16 1
A testSplitDecimalExponent() 0 7 1
A applyDecimalExponentProvider() 0 7 1
A testApplyDecimalExponent() 0 6 1
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+
16
 * @author Daniel Kinzler
17
 */
18
class DecimalParserTest extends StringValueParserTest {
19
20
	/**
21
	 * @see ValueParserTestBase::getInstance
22
	 *
23
	 * @return DecimalParser
24
	 */
25
	protected function getInstance() {
26
		$unlocalizer = $this->getMock( NumberUnlocalizer::class );
27
		$unlocalizer->method( 'unlocalizeNumber' )
28
			->will( $this->returnArgument( 0 ) );
29
30
		return new DecimalParser( null, $unlocalizer );
31
	}
32
33
	/**
34
	 * @see ValueParserTestBase::validInputProvider
35
	 */
36
	public function validInputProvider() {
37
		$argLists = [];
38
39
		$valid = [
40
			'0' => 0,
41
			'-0' => 0,
42
			'-00.00' => '-0.00',
43
			'+00.00' => '+0.00',
44
			'0001' => 1,
45
			'+42' => 42,
46
			'+01' => 01,
47
			'9001' => 9001,
48
			'-1' => -1,
49
			'-42' => -42,
50
			'.5' => 0.5,
51
			'-.125' => -0.125,
52
			'3.' => 3,
53
			',3,' => 3,
54
			'2.125' => 2.125,
55
			'2.1250' => '+2.1250',
56
			'2.1250e0' => '+2.1250',
57
			'2.1250e3' => '+2125.0',
58
			'2.1250e+3' => '+2125.0',
59
			'2.1250e-2' => '+0.021250',
60
			'123e+3' => '+123000',
61
			'123e-2' => '+1.23',
62
			'-123e-5' => '-0.00123',
63
			' 5 ' => 5,
64
			'100,000' => 100000,
65
			'100 000' => 100000,
66
			'100\'000' => 100000,
67
68
			// U+000C (form feed)
69
			"5\f" => 5,
70
			// U+00A0 (non-break space)
71
			"5\xC2\xA0200" => 5200,
72
			// U+202F (narrow no-break space)
73
			"5\xE2\x80\xAF300" => 5300,
74
		];
75
76
		foreach ( $valid as $value => $expected ) {
77
			// Because PHP turns them into ints using black magic
78
			$value = (string)$value;
79
80
			$expected = new DecimalValue( $expected );
81
			$argLists[] = [ $value, $expected ];
82
		}
83
84
		return $argLists;
85
	}
86
87
	/**
88
	 * @see StringValueParserTest::invalidInputProvider
89
	 */
90
	public function invalidInputProvider() {
91
		$argLists = parent::invalidInputProvider();
92
93
		$invalid = [
94
			'foo',
95
			'',
96
			'--1',
97
			'1-',
98
			'one',
99
			'0x20',
100
			'1+1',
101
			'1-1',
102
			'1.2.3',
103
		];
104
105
		foreach ( $invalid as $value ) {
106
			$argLists[] = [ $value ];
107
		}
108
109
		return $argLists;
110
	}
111
112
	public function testUnlocalization() {
113
		$unlocalizer = $this->getMock( NumberUnlocalizer::class );
114
115
		$unlocalizer->expects( $this->once() )
116
			->method( 'unlocalizeNumber' )
117
			->will( $this->returnCallback( function( $number ) {
118
				return str_replace( '#', '', $number );
119
			} ) );
120
121
		$unlocalizer->expects( $this->never() )
122
			->method( 'getNumberRegex' );
123
124
		$unlocalizer->expects( $this->never() )
125
			->method( 'getUnitRegex' );
126
127
		$parser = new DecimalParser( null, $unlocalizer );
128
129
		$input = '###20#000#000###';
130
		/** @var DecimalValue $value */
131
		$value = $parser->parse( $input );
132
133
		$this->assertSame( '+20000000', $value->getValue() );
134
	}
135
136
	public function splitDecimalExponentProvider() {
137
		return [
138
			'trailing newline' => [ "1.2E3\n", '1.2', 3 ],
139
			'whitespace' => [ ' 1.2E3 ', ' 1.2E3 ', 0 ],
140
			'no exponent' => [ '1.2', '1.2', 0 ],
141
			'exponent' => [ '1.2E3', '1.2', 3 ],
142
			'negative exponent' => [ '+1.2e-2', '+1.2', -2 ],
143
			'positive exponent' => [ '-12e+3', '-12', 3 ],
144
			'leading zero' => [ '12e+09', '12', 9 ],
145
			'trailing decimal point' => [ '12.e+3', '12.', 3 ],
146
			'leading decimal point' => [ '.12e+3', '.12', 3 ],
147
			'space' => [ '12 e+3', '12 ', 3 ],
148
			'x10 syntax' => [ '12x10^3', '12', 3 ],
149
			'comma' => [ '12e3,4', '12', 34 ],
150
		];
151
	}
152
153
	/**
154
	 * @dataProvider splitDecimalExponentProvider
155
	 */
156
	public function testSplitDecimalExponent( $valueString, $expectedDecimal, $expectedExponent ) {
157
		$parser = new DecimalParser();
158
		list( $decimal, $exponent ) = $parser->splitDecimalExponent( $valueString );
159
160
		$this->assertSame( $expectedDecimal, $decimal );
161
		$this->assertSame( $expectedExponent, $exponent );
162
	}
163
164
	public function applyDecimalExponentProvider() {
165
		return [
166
			'no exponent' => [ new DecimalValue( '+1.2' ), 0, new DecimalValue( '+1.2' ) ],
167
			'negative exponent' => [ new DecimalValue( '-1.2' ), -2, new DecimalValue( '-0.012' ) ],
168
			'positive exponent' => [ new DecimalValue( '-12' ), 3, new DecimalValue( '-12000' ) ],
169
		];
170
	}
171
172
	/**
173
	 * @dataProvider applyDecimalExponentProvider
174
	 */
175
	public function testApplyDecimalExponent( DecimalValue $decimal, $exponent, DecimalValue $expectedDecimal ) {
176
		$parser = new DecimalParser();
177
		$actualDecimal = $parser->applyDecimalExponent( $decimal, $exponent );
178
179
		$this->assertSame( $expectedDecimal->getValue(), $actualDecimal->getValue() );
180
	}
181
182
}
183