Passed
Pull Request — master (#5)
by Kauri
02:48
created

PaymentPeriodsTest::testPeriod()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 22
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 22
rs 9.2
c 0
b 0
f 0
cc 3
eloc 13
nc 4
nop 2
1
<?php
2
3
namespace Kauri\Loan\Test;
4
5
6
use Kauri\Loan\PaymentPeriods;
7
use Kauri\Loan\Period;
8
use Kauri\Loan\PeriodInterface;
9
use PHPUnit\Framework\TestCase;
10
11
12
class PaymentPeriodsTest extends TestCase
13
{
14
    /**
15
     * @dataProvider periodsData
16
     * @param $averagePeriodLength
17
     * @param $paymentPeriods
18
     */
19
    public function testPaymentPeriods($averagePeriodLength, $paymentPeriods)
20
    {
21
        $periodsCollection = new PaymentPeriods($averagePeriodLength);
22
        $noOfPayments = count($paymentPeriods);
23
        $totalLength = 0;
24
25
        $this->assertEquals(0, $periodsCollection->getNoOfPeriods());
26
        $this->assertTrue(empty($periodsCollection->getPeriods()));
27
28
        foreach ($paymentPeriods as $periodLength) {
29
            $periodMock = $this->getMockPeriod($periodLength);
30
            $periodsCollection->add($periodMock);
31
            $totalLength = $totalLength + $periodLength;
32
        }
33
34
        $periods = $periodsCollection->getPeriods();
35
        $period = current($periods);
36
        $length = $period->getLength();
37
38
        $this->assertEquals($noOfPayments, $periodsCollection->getNoOfPeriods());
39
        $this->assertTrue(!empty($periodsCollection->getPeriods()));
40
41
        $this->assertEquals($totalLength / $length,
42
            $periodsCollection->getNumberOfPeriods($period, $periodsCollection::CALCULATION_MODE_EXACT));
43
        $this->assertEquals($noOfPayments,
44
            $periodsCollection->getNumberOfPeriods($period,
45
                $periodsCollection::CALCULATION_MODE_EXACT_INTEREST));
46
        $this->assertEquals($noOfPayments,
47
            $periodsCollection->getNumberOfPeriods($period, $periodsCollection::CALCULATION_MODE_AVERAGE));
48
49
        $this->assertEquals($length,
50
            $periodsCollection->getRatePerPeriod($period, 360,
51
                $periodsCollection::CALCULATION_MODE_EXACT));
52
        $this->assertEquals($length,
53
            $periodsCollection->getRatePerPeriod($period, 360,
54
                $periodsCollection::CALCULATION_MODE_EXACT_INTEREST));
55
        $this->assertEquals($averagePeriodLength,
56
            $periodsCollection->getRatePerPeriod($period, 360,
57
                $periodsCollection::CALCULATION_MODE_AVERAGE));
58
    }
59
60
    /**
61
     * @dataProvider periodsData
62
     * @param int $averagePeriodLength
63
     * @param array $paymentPeriods
64
     */
65
    public function testPeriod(int $averagePeriodLength, array $paymentPeriods)
66
    {
67
        $periodsCollection = new PaymentPeriods($averagePeriodLength);
68
69
        foreach ($paymentPeriods as $periodLength) {
70
            $periodMock = $this->getMockPeriod($periodLength);
71
            $periodsCollection->add($periodMock);
72
        }
73
74
        $reversedPeriods = array_reverse($paymentPeriods);
75
76
        $periods = $periodsCollection->getPeriods();
77
78
        foreach ($periods as $p) {
79
            array_pop($reversedPeriods);
80
            $exactPeriodsLength = $periodsCollection->getExactPeriodsLength();
81
            $averagePeriodsLength = $periodsCollection->getAveragePeriodsLength();
82
83
            $this->assertEquals($exactPeriodsLength, array_sum($paymentPeriods));
84
            $this->assertEquals($averagePeriodsLength, $averagePeriodLength * count($paymentPeriods));
85
        }
86
    }
87
88
    public function periodsData()
89
    {
90
        return [
91
            [7, [6, 5, 3, 9]],
92
            [30, [29, 30, 31, 30, 28]]
93
        ];
94
    }
95
96
    /**
97
     * @expectedException \Exception
98
     */
99
    public function testRatePerPeriodException()
100
    {
101
        $periodsCollection = new PaymentPeriods(1);
102
        $periodsCollection->getRatePerPeriod($this->getMockPeriod(3), 10, 10);
103
    }
104
105
    /**
106
     * @expectedException \Exception
107
     */
108
    public function testNumberOfPeriodsException()
109
    {
110
        $periodsCollection = new PaymentPeriods(1);
111
        $periodsCollection->getNumberOfPeriods($this->getMockPeriod(3), 10);
112
    }
113
114
    /**
115
     * @param $length
116
     * @return PeriodInterface
117
     */
118
    private function getMockPeriod($length)
119
    {
120
        $stub = $this->getMockBuilder(Period::class)
121
            ->disableOriginalConstructor()
122
            ->setMethods(['getLength'])
123
            ->getMock();
124
125
        $stub->method('getLength')
126
            ->willReturn($length);
127
128
        return $stub;
129
    }
130
131
}
132