Passed
Pull Request — master (#7)
by Alex
07:24
created

testImplementsDateIntervalFactoryInterface()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

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