Completed
Push — master ( 63d015...f4a3a2 )
by Gabriel
12s
created

testEuroStringThatCausedRoundingError_doesNotCauseRoundingError()   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 0
1
<?php
2
3
declare( strict_types = 1 );
4
5
namespace WMDE\Euro\Tests\Unit;
6
7
use PHPUnit\Framework\TestCase;
8
use WMDE\Euro\Euro;
9
10
/**
11
 * @covers \WMDE\Euro\Euro
12
 *
13
 * @license GNU GPL v2+
14
 * @author Jeroen De Dauw < [email protected] >
15
 */
16
class EuroTest extends TestCase {
17
18
	/**
19
	 * @dataProvider unsignedIntegerProvider
20
	 */
21
	public function testGetCentsReturnsConstructorArgument( int $unsignedInteger ) {
22
		$amount = Euro::newFromCents( $unsignedInteger );
23
		$this->assertSame( $unsignedInteger, $amount->getEuroCents() );
24
	}
25
26
	public function unsignedIntegerProvider() {
27
		return [
28
			[ 0 ], [ 1 ], [ 2 ], [ 9 ], [ 10 ], [ 11 ],
29
			[ 99 ], [ 100 ], [ 101 ], [ 999 ], [ 1000 ], [ 1001 ],
30
		];
31
	}
32
33
	public function testGivenZero_getEuroFloatReturnsZeroFloat() {
34
		$amount = Euro::newFromCents( 0 );
35
		$this->assertExactFloat( 0.0, $amount->getEuroFloat() );
36
		$this->assertNotSame( 0, $amount->getEuroFloat() );
37
	}
38
39
	private function assertExactFloat( float $expected, $actual ) {
40
		$this->assertInternalType( 'float', $actual );
41
		$this->assertEquals( $expected, $actual, '', 0 );
42
	}
43
44
	public function testGivenOneEuro_getEuroFloatReturnsOne() {
45
		$amount = Euro::newFromCents( 100 );
46
		$this->assertExactFloat( 1.0, $amount->getEuroFloat() );
47
	}
48
49
	public function testGivenOneCent_getEuroFloatReturnsPointZeroOne() {
50
		$amount = Euro::newFromCents( 1 );
51
		$this->assertExactFloat( 0.01, $amount->getEuroFloat() );
52
	}
53
54
	public function testGiven33cents_getEuroFloatReturnsPointThreeThree() {
55
		$amount = Euro::newFromCents( 33 );
56
		$this->assertExactFloat( 0.33, $amount->getEuroFloat() );
57
	}
58
59
	public function testGivenNegativeAmount_constructorThrowsException() {
60
		$this->expectException( \InvalidArgumentException::class );
61
		Euro::newFromCents( -1 );
62
	}
63
64
	public function testGivenZero_getEuroStringReturnsZeroString() {
65
		$amount = Euro::newFromCents( 0 );
66
		$this->assertSame( '0.00', $amount->getEuroString() );
67
	}
68
69
	public function testGivenOneEuro_getEuroStringReturnsOnePointZeroZero() {
70
		$amount = Euro::newFromCents( 100 );
71
		$this->assertSame( '1.00', $amount->getEuroString() );
72
	}
73
74
	public function testGivenTwoEuros_getEuroStringReturnsTwoPointZeroZero() {
75
		$amount = Euro::newFromCents( 200 );
76
		$this->assertSame( '2.00', $amount->getEuroString() );
77
	}
78
79
	public function testGivenOneCent_getEuroStringReturnsZeroPointZeroOne() {
80
		$amount = Euro::newFromCents( 1 );
81
		$this->assertSame( '0.01', $amount->getEuroString() );
82
	}
83
84
	public function testGivenTenCents_getEuroStringReturnsZeroPointOneZero() {
85
		$amount = Euro::newFromCents( 10 );
86
		$this->assertSame( '0.10', $amount->getEuroString() );
87
	}
88
89
	public function testGiven1234Cents_getEuroStringReturns12euro34() {
90
		$amount = Euro::newFromCents( 1234 );
91
		$this->assertSame( '12.34', $amount->getEuroString() );
92
	}
93
94
	public function testOneEuroString_getsTurnedInto100cents() {
95
		$this->assertSame( 100, Euro::newFromString( '1.00' )->getEuroCents() );
96
	}
97
98
	public function testOneCentString_getsTurnedInto1cents() {
99
		$this->assertSame( 1, Euro::newFromString( '0.01' )->getEuroCents() );
100
	}
101
102
	public function testTenCentString_getsTurnedInto10cents() {
103
		$this->assertSame( 10, Euro::newFromString( '0.10' )->getEuroCents() );
104
	}
105
106
	public function testShortTenCentString_getsTurnedInto10cents() {
107
		$this->assertSame( 10, Euro::newFromString( '0.1' )->getEuroCents() );
108
	}
109
110
	public function testShortOneEuroString_getsTurnedInto100cents() {
111
		$this->assertSame( 100, Euro::newFromString( '1' )->getEuroCents() );
112
	}
113
114
	public function testOneDecimalOneEuroString_getsTurnedInto100cents() {
115
		$this->assertSame( 100, Euro::newFromString( '1.0' )->getEuroCents() );
116
	}
117
118
	public function testMultiDecimalOneEuroString_getsTurnedInto100cents() {
119
		$this->assertSame( 100, Euro::newFromString( '1.00000' )->getEuroCents() );
120
	}
121
122
	public function testHandlingOfLargeEuroString() {
123
		$this->assertSame( 3133742, Euro::newFromString( '31337.42' )->getEuroCents() );
124
	}
125
126
	public function testEuroStringThatCausedRoundingError_doesNotCauseRoundingError() {
127
		// Regression test for https://phabricator.wikimedia.org/T183481
128
		$this->assertSame( 870, Euro::newFromString( '8.70' )->getEuroCents() );
129
		$this->assertSame( 920, Euro::newFromString( '9.20' )->getEuroCents() );
130
	}
131
132
	public function testEuroStringWithRoundingError_getsRoundedAppropriately() {
133
		$this->assertSame( 101, Euro::newFromString( '1.0100000001' )->getEuroCents() );
134
		$this->assertSame( 101, Euro::newFromString( '1.010000009999' )->getEuroCents() );
135
		$this->assertSame( 101, Euro::newFromString( '1.011' )->getEuroCents() );
136
		$this->assertSame( 101, Euro::newFromString( '1.014' )->getEuroCents() );
137
		$this->assertSame( 101, Euro::newFromString( '1.0149' )->getEuroCents() );
138
		$this->assertSame( 102, Euro::newFromString( '1.015' )->getEuroCents() );
139
		$this->assertSame( 102, Euro::newFromString( '1.019' )->getEuroCents() );
140
		$this->assertSame( 102, Euro::newFromString( '1.0199999' )->getEuroCents() );
141
		$this->assertSame( 870, Euro::newFromString( '8.701' )->getEuroCents() );
142
		$this->assertSame( 870, Euro::newFromString( '8.70499' )->getEuroCents() );
143
		$this->assertSame( 871, Euro::newFromString( '8.705' )->getEuroCents() );
144
		$this->assertSame( 871, Euro::newFromString( '8.705000' )->getEuroCents() );
145
		$this->assertSame( 871, Euro::newFromString( '8.705001' )->getEuroCents() );
146
		$this->assertSame( 871, Euro::newFromString( '8.709999' )->getEuroCents() );
147
	}
148
149
	public function testGivenNegativeAmountString_exceptionIsThrown() {
150
		$this->expectException( \InvalidArgumentException::class );
151
		Euro::newFromString( '-1.00' );
152
	}
153
154
	public function testGivenStringWithComma_exceptionIsThrown() {
155
		$this->expectException( \InvalidArgumentException::class );
156
		Euro::newFromString( '1,00' );
157
	}
158
159
	public function testGivenStringWithMultipleDots_ExceptionIsThrown() {
160
		$this->expectException( \InvalidArgumentException::class );
161
		Euro::newFromString( '1.0.0' );
162
	}
163
164
	public function testGivenNonNumber_exceptionIsThrown() {
165
		$this->expectException( \InvalidArgumentException::class );
166
		Euro::newFromString( '1.00abc' );
167
	}
168
169
	public function testGivenNegativeFloatAmount_exceptionIsThrown() {
170
		$this->expectException( \InvalidArgumentException::class );
171
		Euro::newFromFloat( -1.00 );
172
	}
173
174
	public function testOneEuroFloat_getsTurnedInto100cents() {
175
		$this->assertSame( 100, Euro::newFromFloat( 1.0 )->getEuroCents() );
176
	}
177
178
	public function testOneCentFloat_getsTurnedInto1cent() {
179
		$this->assertSame( 1, Euro::newFromFloat( 0.01 )->getEuroCents() );
180
	}
181
182
	public function testTenCentFloat_getsTurnedInto10cents() {
183
		$this->assertSame( 10, Euro::newFromFloat( 0.1 )->getEuroCents() );
184
	}
185
186
	public function testHandlingOfLargeEuroFloat() {
187
		$this->assertSame( 3133742, Euro::newFromFloat( 31337.42 )->getEuroCents() );
188
	}
189
190
	public function testFloatWithRoundingError_getsRoundedAppropriately() {
191
		$this->assertSame( 101, Euro::newFromFloat( 1.0100000001 )->getEuroCents() );
192
		$this->assertSame( 101, Euro::newFromFloat( 1.010000009999 )->getEuroCents() );
193
		$this->assertSame( 101, Euro::newFromFloat( 1.011 )->getEuroCents() );
194
		$this->assertSame( 101, Euro::newFromFloat( 1.014 )->getEuroCents() );
195
		$this->assertSame( 101, Euro::newFromFloat( 1.0149 )->getEuroCents() );
196
		$this->assertSame( 102, Euro::newFromFloat( 1.015 )->getEuroCents() );
197
		$this->assertSame( 102, Euro::newFromFloat( 1.019 )->getEuroCents() );
198
		$this->assertSame( 102, Euro::newFromFloat( 1.0199999 )->getEuroCents() );
199
		$this->assertSame( 870, Euro::newFromFloat( 8.70 )->getEuroCents() );
200
	}
201
202
	public function testZeroEuroIntegers_isZeroCents() {
203
		$this->assertSame( 0, Euro::newFromInt( 0 )->getEuroCents() );
204
	}
205
206
	public function testOneEuroIntegers_is100cents() {
207
		$this->assertSame( 100, Euro::newFromInt( 1 )->getEuroCents() );
208
	}
209
210
	public function test1337EuroIntegers_is133700cents() {
211
		$this->assertSame( 133700, Euro::newFromInt( 1337 )->getEuroCents() );
212
	}
213
214
	public function testGivenNegativeIntegerAmount_exceptionIsThrown() {
215
		$this->expectException( \InvalidArgumentException::class );
216
		Euro::newFromInt( -1 );
217
	}
218
219
	/**
220
	 * @dataProvider euroProvider
221
	 * @param Euro $euro
222
	 */
223
	public function testEuroEqualsItself( Euro $euro ) {
224
		$this->assertTrue( $euro->equals( clone $euro ) );
225
	}
226
227
	public function euroProvider() {
228
		return [
229
			[ Euro::newFromCents( 0 ) ],
230
			[ Euro::newFromCents( 1 ) ],
231
			[ Euro::newFromCents( 99 ) ],
232
			[ Euro::newFromCents( 100 ) ],
233
			[ Euro::newFromCents( 9999 ) ],
234
		];
235
	}
236
237
	public function testOneCentDoesNotEqualOneEuro() {
238
		$this->assertFalse( Euro::newFromCents( 1 )->equals( Euro::newFromInt( 1 ) ) );
239
	}
240
241
	public function testOneCentDoesNotEqualTwoCents() {
242
		$this->assertFalse( Euro::newFromCents( 1 )->equals( Euro::newFromCents( 2 ) ) );
243
	}
244
245
	public function testOneCentDoesNotEqualOneEuroAndOneCent() {
246
		$this->assertFalse( Euro::newFromCents( 1 )->equals( Euro::newFromCents( 101 ) ) );
247
	}
248
249
	public function test9001centsDoesNotEqual9000cents() {
250
		$this->assertFalse( Euro::newFromCents( 9001 )->equals( Euro::newFromCents( 9000 ) ) );
251
	}
252
253
}
254