Passed
Push — master ( 02723f...22c57f )
by Daniel
01:56
created

DecimalParserTest::validInputProvider()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 50
Code Lines 38

Duplication

Lines 0
Ratio 0 %

Importance

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