1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* User: alec |
4
|
|
|
* Date: 05.11.18 |
5
|
|
|
* Time: 21:22 |
6
|
|
|
*/ |
7
|
|
|
declare(strict_types=1); |
8
|
|
|
|
9
|
|
|
namespace Unit\Money; |
10
|
|
|
|
11
|
|
|
|
12
|
|
|
use AlecRabbit\Money\Calculator\BcMathCalculator; |
13
|
|
|
use PHPUnit\Framework\TestCase; |
14
|
|
|
|
15
|
|
|
/** |
16
|
|
|
* @requires extension bcmath |
17
|
|
|
*/ |
18
|
|
|
class BcMathCalculatorTest extends TestCase |
19
|
|
|
{ |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* @dataProvider additionExamples |
23
|
|
|
* @test |
24
|
|
|
* @param $value1 |
25
|
|
|
* @param $value2 |
26
|
|
|
* @param $expected |
27
|
|
|
* @param $scale |
28
|
|
|
*/ |
29
|
|
|
public function it_adds_two_values_with_scale_set($value1, $value2, $expected, $scale): void |
30
|
|
|
{ |
31
|
|
|
$this->assertEquals($expected, $this->getCalculator($scale)->add($value1, $value2)); |
32
|
|
|
} |
33
|
|
|
|
34
|
|
|
protected function getCalculator($scale = null): BcMathCalculator |
35
|
|
|
{ |
36
|
|
|
return new BcMathCalculator($scale); |
37
|
|
|
} |
38
|
|
|
|
39
|
|
|
/** |
40
|
|
|
* @dataProvider subtractionExamples |
41
|
|
|
* @test |
42
|
|
|
* @param $value1 |
43
|
|
|
* @param $value2 |
44
|
|
|
* @param $expected |
45
|
|
|
* @param $scale |
46
|
|
|
*/ |
47
|
|
|
public function it_subtracts_a_value_from_another_with_scale_set($value1, $value2, $expected, $scale): void |
48
|
|
|
{ |
49
|
|
|
$this->assertEquals($expected, $this->getCalculator($scale)->subtract($value1, $value2)); |
50
|
|
|
} |
51
|
|
|
|
52
|
|
|
/** |
53
|
|
|
* @test |
54
|
|
|
*/ |
55
|
|
|
public function it_compares_numbers_close_to_zero(): void |
56
|
|
|
{ |
57
|
|
|
$this->assertEquals(1, $this->getCalculator()->compare('1', '0.0005')); |
58
|
|
|
$this->assertEquals(1, $this->getCalculator()->compare('1', '0.000000000000000000000000005')); |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* @dataProvider additionExamples |
63
|
|
|
* @test |
64
|
|
|
* @param $value1 |
65
|
|
|
* @param $value2 |
66
|
|
|
* @param $expected |
67
|
|
|
* @param $scale |
68
|
|
|
*/ |
69
|
|
|
public function it_adds_two_values($value1, $value2, $expected, $scale): void |
70
|
|
|
{ |
71
|
|
|
$this->assertEquals($expected, $this->getCalculator($scale)->add($value1, $value2)); |
72
|
|
|
} |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @dataProvider subtractionExamples |
76
|
|
|
* @test |
77
|
|
|
* @param $value1 |
78
|
|
|
* @param $value2 |
79
|
|
|
* @param $expected |
80
|
|
|
* @param $scale |
81
|
|
|
*/ |
82
|
|
|
public function it_subtracts_a_value_from_another($value1, $value2, $expected, $scale): void |
83
|
|
|
{ |
84
|
|
|
$this->assertEquals($expected, $this->getCalculator($scale)->subtract($value1, $value2)); |
85
|
|
|
} |
86
|
|
|
|
87
|
|
|
/** |
88
|
|
|
* @dataProvider multiplicationExamples |
89
|
|
|
* @test |
90
|
|
|
* @param $value1 |
91
|
|
|
* @param $value2 |
92
|
|
|
* @param $expected |
93
|
|
|
* @param $scale |
94
|
|
|
*/ |
95
|
|
|
public function it_multiplies_a_value_by_another($value1, $value2, $expected, $scale): void |
96
|
|
|
{ |
97
|
|
|
$this->assertEquals($expected, $this->getCalculator($scale)->multiply($value1, $value2)); |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
/** |
101
|
|
|
* @dataProvider divisionExamples |
102
|
|
|
* @test |
103
|
|
|
* @param $value1 |
104
|
|
|
* @param $value2 |
105
|
|
|
* @param $expected |
106
|
|
|
* @param $scale |
107
|
|
|
*/ |
108
|
|
|
public function it_divides_a_value_by_another($value1, $value2, $expected, $scale): void |
109
|
|
|
{ |
110
|
|
|
$result = $this->getCalculator($scale)->divide($value1, $value2); |
111
|
|
|
$this->assertEquals(substr($expected, 0, \strlen($result)), $result); |
112
|
|
|
} |
113
|
|
|
|
114
|
|
|
/** |
115
|
|
|
* @dataProvider divisionExactExamples |
116
|
|
|
* @test |
117
|
|
|
* @param $value1 |
118
|
|
|
* @param $value2 |
119
|
|
|
* @param $expected |
120
|
|
|
* @param $scale |
121
|
|
|
*/ |
122
|
|
|
public function it_divides_a_value_by_another_exact($value1, $value2, $expected, $scale): void |
123
|
|
|
{ |
124
|
|
|
$this->assertEquals($expected, $this->getCalculator($scale)->divide($value1, $value2)); |
125
|
|
|
} |
126
|
|
|
|
127
|
|
|
/** |
128
|
|
|
* @dataProvider ceilExamples |
129
|
|
|
* @test |
130
|
|
|
* @param $value |
131
|
|
|
* @param $expected |
132
|
|
|
* @param $scale |
133
|
|
|
*/ |
134
|
|
|
public function it_ceil_a_value($value, $expected, $scale): void |
135
|
|
|
{ |
136
|
|
|
$this->assertEquals($expected, $this->getCalculator($scale)->ceil($value)); |
137
|
|
|
} |
138
|
|
|
|
139
|
|
|
/** |
140
|
|
|
* @dataProvider floorProvider |
141
|
|
|
* @test |
142
|
|
|
* @param $value |
143
|
|
|
* @param $expected |
144
|
|
|
*/ |
145
|
|
|
public function it_floors_a_value($expected, $value): void |
146
|
|
|
{ |
147
|
|
|
$this->assertEquals($expected, $this->getCalculator()->floor($value)); |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
public function floorProvider(): array |
151
|
|
|
{ |
152
|
|
|
return [ |
153
|
|
|
['0', -0], |
154
|
|
|
['-1', -0.5], |
155
|
|
|
['-1', -1], |
156
|
|
|
['-2', -1.5], |
157
|
|
|
['-2', -1.8], |
158
|
|
|
['-3', -2.7], |
159
|
|
|
['0', 0], |
160
|
|
|
['0', 0.5], |
161
|
|
|
['1', 1], |
162
|
|
|
['1', 1.5], |
163
|
|
|
['1', 1.8], |
164
|
|
|
['2', 2.7], |
165
|
|
|
['0', '-0'], |
166
|
|
|
['0', ''], |
167
|
|
|
['0', null], |
168
|
|
|
['20000', '2/0000'], |
169
|
|
|
['-60000', '-6/0000'], |
170
|
|
|
['1000000000000000000000000000000', '+1/000000000000000000000000000000'], |
171
|
|
|
[ |
172
|
|
|
'99999999999999999999999999999999999', |
173
|
|
|
'99999999999999999999999999999999999.000000000000000000000', |
174
|
|
|
], |
175
|
|
|
[ |
176
|
|
|
'99999999999999999999999999999999999', |
177
|
|
|
'99999999999999999999999999999999999.999999999999999999999', |
178
|
|
|
], |
179
|
|
|
['0', '0-'], |
180
|
|
|
['100000000000000000000000000000000000', 1.0E+35], |
181
|
|
|
['-100000000000000000000000000000000000', -1.0E+35], |
182
|
|
|
['0', 3E-8], |
183
|
|
|
['0', 1.0E-11], |
184
|
|
|
]; |
185
|
|
|
} |
186
|
|
|
|
187
|
|
|
/** |
188
|
|
|
* @dataProvider absoluteExamples |
189
|
|
|
* @test |
190
|
|
|
* @param $value |
191
|
|
|
* @param $expected |
192
|
|
|
*/ |
193
|
|
|
public function it_calculates_the_absolute_value($expected, $value): void |
194
|
|
|
{ |
195
|
|
|
$this->assertEquals($expected, $this->getCalculator()->absolute($value)); |
196
|
|
|
} |
197
|
|
|
|
198
|
|
|
/** |
199
|
|
|
* @dataProvider shareExamples |
200
|
|
|
* @test |
201
|
|
|
* @param $value |
202
|
|
|
* @param $ratio |
203
|
|
|
* @param $total |
204
|
|
|
* @param $expected |
205
|
|
|
* @param $precision |
206
|
|
|
*/ |
207
|
|
|
public function it_shares_a_value($value, $ratio, $total, $expected, $precision): void |
208
|
|
|
{ |
209
|
|
|
$this->assertEquals($expected, $this->getCalculator($precision)->share($value, $ratio, $total,$precision)); |
210
|
|
|
} |
211
|
|
|
|
212
|
|
|
/** |
213
|
|
|
* @test |
214
|
|
|
* @dataProvider roundProvider |
215
|
|
|
* @param string $expected |
216
|
|
|
* @param int|float|string $number |
217
|
|
|
* @param int $precision |
218
|
|
|
*/ |
219
|
|
|
public function it_rounds_a_value($expected, $number, $precision = 0): void |
220
|
|
|
{ |
221
|
|
|
$number = $this->getCalculator()->round($number, $precision); |
222
|
|
|
self::assertSame($expected, $number); |
223
|
|
|
} |
224
|
|
|
|
225
|
|
|
|
226
|
|
|
/** |
227
|
|
|
* @dataProvider compareExamples |
228
|
|
|
* @test |
229
|
|
|
* @param $left |
230
|
|
|
* @param $right |
231
|
|
|
* @param $expected |
232
|
|
|
* @param $scale |
233
|
|
|
*/ |
234
|
|
|
public function it_compares_values($left, $right, $expected, $scale): void |
235
|
|
|
{ |
236
|
|
|
$this->assertEquals($expected, $this->getCalculator($scale)->compare($left, $right)); |
237
|
|
|
} |
238
|
|
|
|
239
|
|
|
/** |
240
|
|
|
* @dataProvider modProvider |
241
|
|
|
* @test |
242
|
|
|
* @param $left |
243
|
|
|
* @param $right |
244
|
|
|
* @param $expected |
245
|
|
|
* @param $scale |
246
|
|
|
*/ |
247
|
|
|
public function it_calculates_the_modulus_of_a_value($expected, $left, $right, $scale): void |
248
|
|
|
{ |
249
|
|
|
$this->assertEquals($expected, $this->getCalculator($scale)->mod($left, $right)); |
250
|
|
|
} |
251
|
|
|
|
252
|
|
|
public function modProvider(): array |
253
|
|
|
{ |
254
|
|
|
return [ |
255
|
|
|
['1', '11', '2', 0], |
256
|
|
|
['-1', '-1', '5', 0], |
257
|
|
|
['1459434331351930289678', '8728932001983192837219398127471', '1928372132132819737213', 0], |
258
|
|
|
['0', 9.9999E-10, 1, 0], |
259
|
|
|
['0.50', 10.5, 2.5, 2], |
260
|
|
|
['0.50000000000000', 10.5, 2.5, null], |
261
|
|
|
['0.8', '10', '9.2', 1], |
262
|
|
|
['0.0', '20', '4.0', 1], |
263
|
|
|
['0.0', '10.5', '3.5', 1], |
264
|
|
|
['0.3', '10.2', '3.3', 1], |
265
|
|
|
['-0.000559999', 9.9999E-10, -5.6E-4, 9], |
266
|
|
|
]; |
267
|
|
|
} |
268
|
|
|
|
269
|
|
|
public function additionExamples(): array |
270
|
|
|
{ |
271
|
|
|
return [ |
272
|
|
|
[1, 1, '2', 0], |
273
|
|
|
[10, 5, '15', 0], |
274
|
|
|
[10.1, 5.0234, '15.1234', 4], |
275
|
|
|
]; |
276
|
|
|
} |
277
|
|
|
|
278
|
|
|
public function subtractionExamples(): array |
279
|
|
|
{ |
280
|
|
|
return [ |
281
|
|
|
[1, 1, '0', 0], |
282
|
|
|
[10.2, 5.09, '5.11', 2], |
283
|
|
|
[10, 5, '5', 0], |
284
|
|
|
]; |
285
|
|
|
} |
286
|
|
|
|
287
|
|
|
public function multiplicationExamples(): array |
288
|
|
|
{ |
289
|
|
|
return [ |
290
|
|
|
[1, 1.5, '1.5', 1], |
291
|
|
|
[10, 1.2500, '12.50', 2], |
292
|
|
|
[100, 0.29, '29', 0], |
293
|
|
|
[100, 0.029, '2.9', 1], |
294
|
|
|
[100, 0.0029, '0.29', 2], |
295
|
|
|
[1000, 0.29, '290', 0], |
296
|
|
|
[1000, 0.029, '29', 0], |
297
|
|
|
[0.2424, 0.029, '0.0070296', 8], |
298
|
|
|
[1000, 0.0029, '2.9', 1], |
299
|
|
|
[2000, 0.0029, '5.8', 1], |
300
|
|
|
['1', 0.006597, '0.006597', 6], |
301
|
|
|
]; |
302
|
|
|
} |
303
|
|
|
|
304
|
|
|
public function divisionExamples(): array |
305
|
|
|
{ |
306
|
|
|
return [ |
307
|
|
|
[6, 3, '2', 0], |
308
|
|
|
[100, 25, '4', 0], |
309
|
|
|
[2, 4, '0.5', 1], |
310
|
|
|
[20, 0.5, '40', 0], |
311
|
|
|
[2, 0.5, '4', 0], |
312
|
|
|
['1.72', 1.36, '1.26470588235294', 14], |
313
|
|
|
[181, 17, '10.64705882352941', 1], |
314
|
|
|
[98, 28, '3.5', 1], |
315
|
|
|
[98, 25, '3.92', 2], |
316
|
|
|
[98, 24, '4.083333333333333', 15], |
317
|
|
|
[1, 5.1555, '0.19396760740956', 14], |
318
|
|
|
]; |
319
|
|
|
} |
320
|
|
|
|
321
|
|
|
public function divisionExactExamples(): array |
322
|
|
|
{ |
323
|
|
|
return [ |
324
|
|
|
[6, 3, '2', 0], |
325
|
|
|
[100, 25, '4', 0], |
326
|
|
|
[2, 4, '0.5', 1], |
327
|
|
|
[20, 0.5, '40', 0], |
328
|
|
|
[2, 0.5, '4', 0], |
329
|
|
|
[98, 28, '3.5', 1], |
330
|
|
|
[98, 25, '3.92', 2], |
331
|
|
|
]; |
332
|
|
|
} |
333
|
|
|
|
334
|
|
|
public function ceilExamples(): array |
335
|
|
|
{ |
336
|
|
|
return [ |
337
|
|
|
[1.2, '2', 0], |
338
|
|
|
[-1.2, '-1', 0], |
339
|
|
|
[2.00, '2', 0], |
340
|
|
|
[1.2, '2', 5], |
341
|
|
|
[-1.2, '-1', 2], |
342
|
|
|
[2.00, '2', 3], |
343
|
|
|
]; |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
public function floorExamples(): array |
347
|
|
|
{ |
348
|
|
|
return [ |
349
|
|
|
[2.7, '2', 0], |
350
|
|
|
[-2.7, '-3', 0], |
351
|
|
|
[2.00, '2', 0], |
352
|
|
|
]; |
353
|
|
|
} |
354
|
|
|
|
355
|
|
|
public function absoluteExamples(): array |
356
|
|
|
{ |
357
|
|
|
return [ |
358
|
|
|
['1', -1], |
359
|
|
|
['1.5', -1.5], |
360
|
|
|
['1', '-1'], |
361
|
|
|
['1.5', '-1.5'], |
362
|
|
|
[ |
363
|
|
|
'9999999999999999999999999999999999999999999999999999999', |
364
|
|
|
'-9999999999999999999999999999999999999999999999999999999', |
365
|
|
|
], |
366
|
|
|
['0', '-0'], |
367
|
|
|
['0', ''], |
368
|
|
|
['0', null], |
369
|
|
|
['20000', '2/0000'], |
370
|
|
|
['60000', '-6/0000'], |
371
|
|
|
['1000000000000000000000000000000', '+1/000000000000000000000000000000'], |
372
|
|
|
['0', '0-'], |
373
|
|
|
['100000000000000000000000000000000000', 1.0E+35], |
374
|
|
|
['100000000000000000000000000000000000', -1.0E+35], |
375
|
|
|
['0.0000051', -5.1E-6], |
376
|
|
|
]; |
377
|
|
|
} |
378
|
|
|
|
379
|
|
|
public function shareExamples(): array |
380
|
|
|
{ |
381
|
|
|
return [ |
382
|
|
|
[10, 2, 4, '5', 0], |
383
|
|
|
]; |
384
|
|
|
} |
385
|
|
|
|
386
|
|
|
public function compareExamples(): array |
387
|
|
|
{ |
388
|
|
|
return [ |
389
|
|
|
[1, 0, 1, 0], |
390
|
|
|
[1, 1, 0, 0], |
391
|
|
|
[0, 1, -1, 0], |
392
|
|
|
['1', '0', 1, 0], |
393
|
|
|
['1', '1', 0, 0], |
394
|
|
|
['0', '1', -1, 0], |
395
|
|
|
['1', '0.0005', 1, 0], |
396
|
|
|
['1', '0.000000000000000000000000005', 1, 0], |
397
|
|
|
]; |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
public function roundProvider(): array |
401
|
|
|
{ |
402
|
|
|
return [ |
403
|
|
|
['3', '3.4'], |
404
|
|
|
['4', '3.5'], |
405
|
|
|
['4', '3.6'], |
406
|
|
|
['2', '1.95583'], |
407
|
|
|
['2', '1.95583'], |
408
|
|
|
['1.96', '1.95583', 2], |
409
|
|
|
['1.956', '1.95583', 3], |
410
|
|
|
['1.9558', '1.95583', 4], |
411
|
|
|
['1.95583', '1.95583', 5], |
412
|
|
|
['1241757', '1241757'], |
413
|
|
|
['1241757', '1241757', 5], |
414
|
|
|
['-3', '-3.4'], |
415
|
|
|
['-4', '-3.5'], |
416
|
|
|
['-4', '-3.6'], |
417
|
|
|
['123456.745671', '123456.7456713', 6], |
418
|
|
|
['1', '1.11'], |
419
|
|
|
['1.11', '1.11', 2], |
420
|
|
|
['0.1666666666667', '0.1666666666666665', 13], |
421
|
|
|
['0', '0.1666666666666665', 0.13], |
422
|
|
|
['10', '9.999'], |
423
|
|
|
['10.00', '9.999', 2], |
424
|
|
|
['0.01', '0.005', 2], |
425
|
|
|
['0.02', '0.015', 2], |
426
|
|
|
['0.03', '0.025', 2], |
427
|
|
|
['0.04', '0.035', 2], |
428
|
|
|
['0.05', '0.045', 2], |
429
|
|
|
['0.06', '0.055', 2], |
430
|
|
|
['0.07', '0.065', 2], |
431
|
|
|
['0.08', '0.075', 2], |
432
|
|
|
['0.09', '0.085', 2], |
433
|
|
|
['77777777777777777777777777777', '77777777777777777777777777777.1'], |
434
|
|
|
[ |
435
|
|
|
'100000000000000000000000000000000000', |
436
|
|
|
'99999999999999999999999999999999999.99999999999999999999999999999999991', |
437
|
|
|
], |
438
|
|
|
[ |
439
|
|
|
'99999999999999999999999999999999999', |
440
|
|
|
'99999999999999999999999999999999999.00000000000000000000000000000000001', |
441
|
|
|
], |
442
|
|
|
['99999999999999999999999999999999999', '99999999999999999999999999999999999.000000000000000000000'], |
443
|
|
|
['0', '-0'], |
444
|
|
|
['0', ''], |
445
|
|
|
['0', null], |
446
|
|
|
['20000', '2/0000'], |
447
|
|
|
['-60000', '-6/0000'], |
448
|
|
|
['1000000000000000000000000000000', '+1/000000000000000000000000000000'], |
449
|
|
|
['0', '0-'], |
450
|
|
|
['100000000000000000000000000000000000', 1.0E+35], |
451
|
|
|
['-100000000000000000000000000000000000', -1.0E+35], |
452
|
|
|
['0', 3E-8], |
453
|
|
|
['0', 1.0E-11], |
454
|
|
|
['-0.0006', -5.6E-4, 4], |
455
|
|
|
['0.0000000010', 9.9999E-10, 10], |
456
|
|
|
]; |
457
|
|
|
} |
458
|
|
|
|
459
|
|
|
} |