Completed
Pull Request — master (#11)
by Tim
03:25
created

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