Passed
Pull Request — master (#7)
by Alex
08:15
created

testDiffWillReturnValidDateInterval()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
c 0
b 0
f 0
dl 0
loc 19
rs 9.9666
cc 1
nc 1
nop 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace ArpTest\DateTime;
6
7
use Arp\DateTime\DateIntervalFactory;
8
use Arp\DateTime\DateIntervalFactoryInterface;
9
use Arp\DateTime\Exception\DateIntervalFactoryException;
10
use PHPUnit\Framework\MockObject\MockObject;
11
use PHPUnit\Framework\TestCase;
12
13
/**
14
 * @author  Alex Patterson <[email protected]>
15
 * @package ArpTest\DateTime
16
 */
17
final class DateIntervalFactoryTest extends TestCase
18
{
19
    /**
20
     * Ensure that the DateIntervalFactory implements the DateIntervalFactoryInterface.
21
     *
22
     * @covers \Arp\DateTime\DateIntervalFactory
23
     */
24
    public function testImplementsDateIntervalFactoryInterface(): void
25
    {
26
        $factory = new DateIntervalFactory();
27
28
        $this->assertInstanceOf(DateIntervalFactoryInterface::class, $factory);
29
    }
30
31
    /**
32
     * Ensure that the DateInterval is created in accordance with the provided $spec.
33
     *
34
     * @param string $spec The \DateInterval specification.
35
     *
36
     * @dataProvider getCreateDateIntervalData
37
     *
38
     * @covers       \Arp\DateTime\DateIntervalFactory::createDateInterval
39
     *
40
     * @throws DateIntervalFactoryException
41
     */
42
    public function testCreateDateInterval(string $spec): void
43
    {
44
        $factory = new DateIntervalFactory();
45
46
        $dateInterval = $factory->createDateInterval($spec);
47
48
        $test = new \DateInterval($spec);
49
50
        $this->assertSame($test->y, $dateInterval->y);
51
        $this->assertSame($test->m, $dateInterval->m);
52
        $this->assertSame($test->d, $dateInterval->d);
53
        $this->assertSame($test->h, $dateInterval->h);
54
        $this->assertSame($test->i, $dateInterval->i);
55
        $this->assertSame($test->f, $dateInterval->f);
56
    }
57
58
    /**
59
     * @see https://www.php.net/manual/en/class.dateinterval.php
60
     *
61
     * @return array
62
     */
63
    public function getCreateDateIntervalData(): array
64
    {
65
        return [
66
            ['P100D'],
67
            ['P4Y1DT9H11M3S'],
68
            ['P2Y4DT6H8M'],
69
            ['P7Y8M'],
70
        ];
71
    }
72
73
    /**
74
     * Ensure that createDateInterval() will throw a DateIntervalFactoryException if the provided $spec is invalid.
75
     *
76
     * @param string $spec
77
     *
78
     * @covers       \Arp\DateTime\DateIntervalFactory::createDateInterval
79
     * @dataProvider getCreateDateIntervalWillThrowDateIntervalFactoryExceptionData
80
     *
81
     * @throws DateIntervalFactoryException
82
     */
83
    public function testCreateDateIntervalWillThrowDateIntervalFactoryException(string $spec): void
84
    {
85
        $factory = new DateIntervalFactory();
86
87
        $exceptionMessage = sprintf('DateInterval::__construct(): Unknown or bad format (%s)', $spec);
88
89
        $this->expectException(DateIntervalFactoryException::class);
90
        $this->expectExceptionMessage(
91
            sprintf(
92
                'Failed to create a valid \DateInterval instance using \'%s\': %s',
93
                $spec,
94
                $exceptionMessage
95
            )
96
        );
97
98
        $factory->createDateInterval($spec);
99
    }
100
101
    /**
102
     * @return array
103
     */
104
    public function getCreateDateIntervalWillThrowDateIntervalFactoryExceptionData(): array
105
    {
106
        return [
107
            ['test'],
108
            ['invalid'],
109
        ];
110
    }
111
112
    /**
113
     * Assert that a DateIntervalFactoryException is thrown when the date diff fails
114
     *
115
     * @covers \Arp\DateTime\DateIntervalFactory::diff
116
     *
117
     * @throws DateIntervalFactoryException
118
     */
119
    public function testDiffWillThrowDateIntervalFactoryExceptionIfDateIntervalCannotBeCreated(): void
120
    {
121
        $factory = new DateIntervalFactory();
122
123
        /** @var \DateTime|MockObject $target */
124
        $target = $this->createMock(\DateTime::class);
125
126
        /** @var \DateTime|MockObject $origin */
127
        $origin = $this->createMock(\DateTime::class);
128
129
        $origin->expects($this->once())
130
            ->method('diff')
131
            ->with($target, false)
132
            ->willReturn(false);
133
134
        $this->expectException(DateIntervalFactoryException::class);
135
        $this->expectExceptionMessage('Failed to create valid \DateInterval while performing date diff');
136
137
        $factory->diff($origin, $target);
138
    }
139
140
    /**
141
     * Assert that a valid \DateInterval is returned from the calls to diff().
142
     *
143
     * @covers \Arp\DateTime\DateIntervalFactory::diff
144
     *
145
     * @throws DateIntervalFactoryException
146
     */
147
    public function testDiffWillReturnValidDateInterval(): void
148
    {
149
        $factory = new DateIntervalFactory();
150
151
        /** @var \DateTime|MockObject $target */
152
        $target = $this->createMock(\DateTime::class);
153
154
        /** @var \DateTime|MockObject $origin */
155
        $origin = $this->createMock(\DateTime::class);
156
157
        /** @var \DateInterval|MockObject $dateInterval */
158
        $dateInterval = $this->createMock(\DateInterval::class);
159
160
        $origin->expects($this->once())
161
            ->method('diff')
162
            ->with($target, false)
163
            ->willReturn($dateInterval);
164
165
        $this->assertSame($dateInterval, $factory->diff($origin, $target));
166
    }
167
}
168