Completed
Pull Request — master (#11)
by Tim
05:23
created

testGiven1234Cents_stringCastingReturns12euro34()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
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 testGiven1234Cents_stringCastingReturns12euro34() {
95
		$amount = Euro::newFromCents( 9876 );
96
		$this->assertSame( '98.76', (string) $amount );
97
	}
98
99
	public function testOneEuroString_getsTurnedInto100cents() {
100
		$this->assertSame( 100, Euro::newFromString( '1.00' )->getEuroCents() );
101
	}
102
103
	public function testOneCentString_getsTurnedInto1cents() {
104
		$this->assertSame( 1, Euro::newFromString( '0.01' )->getEuroCents() );
105
	}
106
107
	public function testTenCentString_getsTurnedInto10cents() {
108
		$this->assertSame( 10, Euro::newFromString( '0.10' )->getEuroCents() );
109
	}
110
111
	public function testShortTenCentString_getsTurnedInto10cents() {
112
		$this->assertSame( 10, Euro::newFromString( '0.1' )->getEuroCents() );
113
	}
114
115
	public function testShortOneEuroString_getsTurnedInto100cents() {
116
		$this->assertSame( 100, Euro::newFromString( '1' )->getEuroCents() );
117
	}
118
119
	public function testOneDecimalOneEuroString_getsTurnedInto100cents() {
120
		$this->assertSame( 100, Euro::newFromString( '1.0' )->getEuroCents() );
121
	}
122
123
	public function testMultiDecimalOneEuroString_getsTurnedInto100cents() {
124
		$this->assertSame( 100, Euro::newFromString( '1.00000' )->getEuroCents() );
125
	}
126
127
	public function testHandlingOfLargeEuroString() {
128
		$this->assertSame( 3133742, Euro::newFromString( '31337.42' )->getEuroCents() );
129
	}
130
131
	public function testEuroStringThatCausedRoundingError_doesNotCauseRoundingError() {
132
		// Regression test for https://phabricator.wikimedia.org/T183481
133
		$this->assertSame( 870, Euro::newFromString( '8.70' )->getEuroCents() );
134
		$this->assertSame( 920, Euro::newFromString( '9.20' )->getEuroCents() );
135
	}
136
137
	public function testEuroStringWithRoundingError_getsRoundedAppropriately() {
138
		$this->assertSame( 101, Euro::newFromString( '1.0100000001' )->getEuroCents() );
139
		$this->assertSame( 101, Euro::newFromString( '1.010000009999' )->getEuroCents() );
140
		$this->assertSame( 101, Euro::newFromString( '1.011' )->getEuroCents() );
141
		$this->assertSame( 101, Euro::newFromString( '1.014' )->getEuroCents() );
142
		$this->assertSame( 101, Euro::newFromString( '1.0149' )->getEuroCents() );
143
		$this->assertSame( 102, Euro::newFromString( '1.015' )->getEuroCents() );
144
		$this->assertSame( 102, Euro::newFromString( '1.019' )->getEuroCents() );
145
		$this->assertSame( 102, Euro::newFromString( '1.0199999' )->getEuroCents() );
146
		$this->assertSame( 870, Euro::newFromString( '8.701' )->getEuroCents() );
147
		$this->assertSame( 870, Euro::newFromString( '8.70499' )->getEuroCents() );
148
		$this->assertSame( 871, Euro::newFromString( '8.705' )->getEuroCents() );
149
		$this->assertSame( 871, Euro::newFromString( '8.705000' )->getEuroCents() );
150
		$this->assertSame( 871, Euro::newFromString( '8.705001' )->getEuroCents() );
151
		$this->assertSame( 871, Euro::newFromString( '8.709999' )->getEuroCents() );
152
	}
153
154
	public function testGivenNegativeAmountString_exceptionIsThrown() {
155
		$this->expectException( \InvalidArgumentException::class );
156
		Euro::newFromString( '-1.00' );
157
	}
158
159
	public function testGivenStringWithComma_exceptionIsThrown() {
160
		$this->expectException( \InvalidArgumentException::class );
161
		Euro::newFromString( '1,00' );
162
	}
163
164
	public function testGivenStringWithMultipleDots_ExceptionIsThrown() {
165
		$this->expectException( \InvalidArgumentException::class );
166
		Euro::newFromString( '1.0.0' );
167
	}
168
169
	public function testGivenNonNumber_exceptionIsThrown() {
170
		$this->expectException( \InvalidArgumentException::class );
171
		Euro::newFromString( '1.00abc' );
172
	}
173
174
	public function testGivenNegativeFloatAmount_exceptionIsThrown() {
175
		$this->expectException( \InvalidArgumentException::class );
176
		Euro::newFromFloat( -1.00 );
177
	}
178
179
	public function testOneEuroFloat_getsTurnedInto100cents() {
180
		$this->assertSame( 100, Euro::newFromFloat( 1.0 )->getEuroCents() );
181
	}
182
183
	public function testOneCentFloat_getsTurnedInto1cent() {
184
		$this->assertSame( 1, Euro::newFromFloat( 0.01 )->getEuroCents() );
185
	}
186
187
	public function testTenCentFloat_getsTurnedInto10cents() {
188
		$this->assertSame( 10, Euro::newFromFloat( 0.1 )->getEuroCents() );
189
	}
190
191
	public function testHandlingOfLargeEuroFloat() {
192
		$this->assertSame( 3133742, Euro::newFromFloat( 31337.42 )->getEuroCents() );
193
	}
194
195
	public function testFloatWithRoundingError_getsRoundedAppropriately() {
196
		$this->assertSame( 101, Euro::newFromFloat( 1.0100000001 )->getEuroCents() );
197
		$this->assertSame( 101, Euro::newFromFloat( 1.010000009999 )->getEuroCents() );
198
		$this->assertSame( 101, Euro::newFromFloat( 1.011 )->getEuroCents() );
199
		$this->assertSame( 101, Euro::newFromFloat( 1.014 )->getEuroCents() );
200
		$this->assertSame( 101, Euro::newFromFloat( 1.0149 )->getEuroCents() );
201
		$this->assertSame( 102, Euro::newFromFloat( 1.015 )->getEuroCents() );
202
		$this->assertSame( 102, Euro::newFromFloat( 1.019 )->getEuroCents() );
203
		$this->assertSame( 102, Euro::newFromFloat( 1.0199999 )->getEuroCents() );
204
		$this->assertSame( 870, Euro::newFromFloat( 8.70 )->getEuroCents() );
205
	}
206
207
	public function testZeroEuroIntegers_isZeroCents() {
208
		$this->assertSame( 0, Euro::newFromInt( 0 )->getEuroCents() );
209
	}
210
211
	public function testOneEuroIntegers_is100cents() {
212
		$this->assertSame( 100, Euro::newFromInt( 1 )->getEuroCents() );
213
	}
214
215
	public function test1337EuroIntegers_is133700cents() {
216
		$this->assertSame( 133700, Euro::newFromInt( 1337 )->getEuroCents() );
217
	}
218
219
	public function testGivenNegativeIntegerAmount_exceptionIsThrown() {
220
		$this->expectException( \InvalidArgumentException::class );
221
		Euro::newFromInt( -1 );
222
	}
223
224
	/**
225
	 * @dataProvider euroProvider
226
	 * @param Euro $euro
227
	 */
228
	public function testEuroEqualsItself( Euro $euro ) {
229
		$this->assertTrue( $euro->equals( clone $euro ) );
230
	}
231
232
	public function euroProvider() {
233
		return [
234
			[ Euro::newFromCents( 0 ) ],
235
			[ Euro::newFromCents( 1 ) ],
236
			[ Euro::newFromCents( 99 ) ],
237
			[ Euro::newFromCents( 100 ) ],
238
			[ Euro::newFromCents( 9999 ) ],
239
		];
240
	}
241
242
	public function testOneCentDoesNotEqualOneEuro() {
243
		$this->assertFalse( Euro::newFromCents( 1 )->equals( Euro::newFromInt( 1 ) ) );
244
	}
245
246
	public function testOneCentDoesNotEqualTwoCents() {
247
		$this->assertFalse( Euro::newFromCents( 1 )->equals( Euro::newFromCents( 2 ) ) );
248
	}
249
250
	public function testOneCentDoesNotEqualOneEuroAndOneCent() {
251
		$this->assertFalse( Euro::newFromCents( 1 )->equals( Euro::newFromCents( 101 ) ) );
252
	}
253
254
	public function test9001centsDoesNotEqual9000cents() {
255
		$this->assertFalse( Euro::newFromCents( 9001 )->equals( Euro::newFromCents( 9000 ) ) );
256
	}
257
258
}
259