Passed
Push — phpstan ( c4fbd2...07dbe1 )
by Sam
08:10
created

DBDatetimeTest::modifyProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 17
Code Lines 15

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 15
nc 1
nop 0
dl 0
loc 17
rs 9.7666
c 1
b 0
f 0
1
<?php
2
3
namespace SilverStripe\ORM\Tests;
4
5
use SilverStripe\Dev\SapphireTest;
6
use SilverStripe\i18n\i18n;
7
use SilverStripe\ORM\FieldType\DBDatetime;
8
9
/**
10
 * Tests for {@link Datetime} class.
11
 */
12
class DBDatetimeTest extends SapphireTest
13
{
14
    protected function setUp()
15
    {
16
        parent::setUp();
17
        i18n::set_locale('en_NZ');
18
    }
19
20
    public function testNowWithSystemDate()
21
    {
22
        $systemDatetime = DBDatetime::create_field('Datetime', date('Y-m-d H:i:s'));
23
        $nowDatetime = DBDatetime::now();
24
25
        $this->assertEquals($systemDatetime->Date(), $nowDatetime->Date());
0 ignored issues
show
Bug introduced by
The method Date() does not exist on SilverStripe\ORM\FieldType\DBField. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

25
        $this->assertEquals($systemDatetime->/** @scrutinizer ignore-call */ Date(), $nowDatetime->Date());
Loading history...
26
    }
27
28
    public function testNowWithMockDate()
29
    {
30
        // Test setting
31
        $mockDate = '2001-12-31 22:10:59';
32
        DBDatetime::set_mock_now($mockDate);
33
        $systemDatetime = DBDatetime::create_field('Datetime', date('Y-m-d H:i:s'));
34
        $nowDatetime = DBDatetime::now();
35
        $this->assertNotEquals($systemDatetime->Date(), $nowDatetime->Date());
36
        $this->assertEquals($nowDatetime->getValue(), $mockDate);
37
38
        // Test clearing
39
        DBDatetime::clear_mock_now();
40
        $systemDatetime = DBDatetime::create_field('Datetime', date('Y-m-d H:i:s'));
41
        $nowDatetime = DBDatetime::now();
42
        $this->assertEquals($systemDatetime->Date(), $nowDatetime->Date());
43
    }
44
45
    public function testSetNullAndZeroValues()
46
    {
47
        $date = DBDatetime::create_field('Datetime', '');
48
        $this->assertNull($date->getValue(), 'Empty string evaluates to NULL');
49
50
        $date = DBDatetime::create_field('Datetime', null);
51
        $this->assertNull($date->getValue(), 'NULL is set as NULL');
52
53
        $date = DBDatetime::create_field('Datetime', false);
54
        $this->assertNull($date->getValue(), 'Boolean FALSE evaluates to NULL');
55
56
        $date = DBDatetime::create_field('Datetime', '0');
57
        $this->assertEquals('1970-01-01 00:00:00', $date->getValue(), 'String zero is UNIX epoch time');
58
59
        $date = DBDatetime::create_field('Datetime', 0);
60
        $this->assertEquals('1970-01-01 00:00:00', $date->getValue(), 'Numeric zero is UNIX epoch time');
61
    }
62
63
    public function testExtendedDateTimes()
64
    {
65
        $date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
66
        $this->assertEquals('10 Oct 1600 15 32 24', $date->Format('d MMM y H m s'));
0 ignored issues
show
Bug introduced by
The method Format() does not exist on SilverStripe\ORM\FieldType\DBField. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

66
        $this->assertEquals('10 Oct 1600 15 32 24', $date->/** @scrutinizer ignore-call */ Format('d MMM y H m s'));
Loading history...
67
68
        $date = DBDatetime::create_field('Datetime', '3000-10-10 15:32:24');
69
        $this->assertEquals('10 Oct 3000 15 32 24', $date->Format('d MMM y H m s'));
70
    }
71
72
    /**
73
     * Coverage for dates using hindi-numerals
74
     */
75
    public function testHindiNumerals()
76
    {
77
        // Parent locale is english; Can be localised to arabic
78
        $date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
79
        $this->assertEquals('10 Oct 1600 15 32 24', $date->Format('d MMM y H m s'));
80
        $this->assertEquals('١٠ أكتوبر ١٦٠٠ ١٥ ٣٢ ٢٤', $date->Format('d MMM y H m s', 'ar'));
81
82
        // Parent locale is arabic; Datavalue uses ISO date
83
        i18n::set_locale('ar');
84
        $date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
85
        $this->assertEquals('١٠ أكتوبر ١٦٠٠ ١٥ ٣٢ ٢٤', $date->Format('d MMM y H m s'));
86
        $this->assertEquals('1600-10-10 15:32:24', $date->getValue());
87
    }
88
89
    public function testNice()
90
    {
91
        $date = DBDatetime::create_field('Datetime', '2001-12-11 22:10:59');
92
93
        // note: Some localisation packages exclude the ',' in default medium format
94
        i18n::set_locale('en_NZ');
95
        $this->assertRegExp('#11/12/2001(,)? 10:10 PM#i', $date->Nice());
0 ignored issues
show
Bug introduced by
The method Nice() does not exist on SilverStripe\ORM\FieldType\DBField. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

95
        $this->assertRegExp('#11/12/2001(,)? 10:10 PM#i', $date->/** @scrutinizer ignore-call */ Nice());
Loading history...
96
97
        i18n::set_locale('en_US');
98
        $this->assertRegExp('#Dec 11(,)? 2001(,)? 10:10 PM#i', $date->Nice());
99
    }
100
101
    public function testDate()
102
    {
103
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
104
        $this->assertEquals('31/12/2001', $date->Date());
105
    }
106
107
    public function testTime()
108
    {
109
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
110
        $this->assertRegexp('#10:10:59 PM#i', $date->Time());
0 ignored issues
show
Bug introduced by
The method Time() does not exist on SilverStripe\ORM\FieldType\DBField. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

110
        $this->assertRegexp('#10:10:59 PM#i', $date->/** @scrutinizer ignore-call */ Time());
Loading history...
111
    }
112
113
    public function testTime24()
114
    {
115
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
116
        $this->assertEquals('22:10', $date->Time24());
0 ignored issues
show
Bug introduced by
The method Time24() does not exist on SilverStripe\ORM\FieldType\DBField. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

116
        $this->assertEquals('22:10', $date->/** @scrutinizer ignore-call */ Time24());
Loading history...
117
    }
118
119
    public function testURLDateTime()
120
    {
121
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
122
        $this->assertEquals('2001-12-31%2022%3A10%3A59', $date->URLDateTime());
0 ignored issues
show
Bug introduced by
The method URLDateTime() does not exist on SilverStripe\ORM\FieldType\DBField. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

122
        $this->assertEquals('2001-12-31%2022%3A10%3A59', $date->/** @scrutinizer ignore-call */ URLDateTime());
Loading history...
123
    }
124
125
    public function testAgoInPast()
126
    {
127
        DBDatetime::set_mock_now('2000-12-31 12:00:00');
128
129
        $this->assertEquals(
130
            '10 years ago',
131
            DBDatetime::create_field('Datetime', '1990-12-31 12:00:00')->Ago(),
0 ignored issues
show
Bug introduced by
The method Ago() does not exist on SilverStripe\ORM\FieldType\DBField. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

131
            DBDatetime::create_field('Datetime', '1990-12-31 12:00:00')->/** @scrutinizer ignore-call */ Ago(),
Loading history...
132
            'Exact past match on years'
133
        );
134
135
        $this->assertEquals(
136
            '10 years ago',
137
            DBDatetime::create_field('Datetime', '1990-12-30 12:00:00')->Ago(),
138
            'Approximate past match on years'
139
        );
140
141
        $this->assertEquals(
142
            '1 year ago',
143
            DBDatetime::create_field('Datetime', '1999-12-30 12:00:12')->Ago(true, 1),
144
            'Approximate past match in singular, significance=1'
145
        );
146
147
        $this->assertEquals(
148
            '12 months ago',
149
            DBDatetime::create_field('Datetime', '1999-12-30 12:00:12')->Ago(),
150
            'Approximate past match in singular'
151
        );
152
153
        $this->assertEquals(
154
            '50 mins ago',
155
            DBDatetime::create_field('Datetime', '2000-12-31 11:10:11')->Ago(),
156
            'Approximate past match on minutes'
157
        );
158
159
        $this->assertEquals(
160
            '59 secs ago',
161
            DBDatetime::create_field('Datetime', '2000-12-31 11:59:01')->Ago(),
162
            'Approximate past match on seconds'
163
        );
164
165
        $this->assertEquals(
166
            'less than a minute ago',
167
            DBDatetime::create_field('Datetime', '2000-12-31 11:59:01')->Ago(false),
168
            'Approximate past match on seconds with $includeSeconds=false'
169
        );
170
171
        $this->assertEquals(
172
            '1 min ago',
173
            DBDatetime::create_field('Datetime', '2000-12-31 11:58:50')->Ago(false),
174
            'Test between 1 and 2 minutes with includeSeconds=false'
175
        );
176
177
        $this->assertEquals(
178
            '70 secs ago',
179
            DBDatetime::create_field('Datetime', '2000-12-31 11:58:50')->Ago(true),
180
            'Test between 1 and 2 minutes with includeSeconds=true'
181
        );
182
183
        $this->assertEquals(
184
            '4 mins ago',
185
            DBDatetime::create_field('Datetime', '2000-12-31 11:55:50')->Ago(),
186
            'Past match on minutes'
187
        );
188
189
        $this->assertEquals(
190
            '1 hour ago',
191
            DBDatetime::create_field('Datetime', '2000-12-31 10:50:58')->Ago(true, 1),
192
            'Past match on hours, significance=1'
193
        );
194
195
        $this->assertEquals(
196
            '3 hours ago',
197
            DBDatetime::create_field('Datetime', '2000-12-31 08:50:58')->Ago(),
198
            'Past match on hours'
199
        );
200
201
        DBDatetime::clear_mock_now();
202
    }
203
204
    public function testAgoInFuture()
205
    {
206
        DBDatetime::set_mock_now('2000-12-31 00:00:00');
207
208
        $this->assertEquals(
209
            'in 10 years',
210
            DBDatetime::create_field('Datetime', '2010-12-31 12:00:00')->Ago(),
211
            'Exact past match on years'
212
        );
213
214
        $this->assertEquals(
215
            'in 1 hour',
216
            DBDatetime::create_field('Datetime', '2000-12-31 1:01:05')->Ago(true, 1),
217
            'Approximate past match on minutes, significance=1'
218
        );
219
220
        $this->assertEquals(
221
            'in 61 mins',
222
            DBDatetime::create_field('Datetime', '2000-12-31 1:01:05')->Ago(),
223
            'Approximate past match on minutes'
224
        );
225
226
        DBDatetime::clear_mock_now();
227
    }
228
229
    public function testRfc3999()
230
    {
231
        // Dates should be formatted as: 2018-01-24T14:05:53+00:00
232
        $date = DBDatetime::create_field('Datetime', '2010-12-31 16:58:59');
233
        $this->assertEquals('2010-12-31T16:58:59+00:00', $date->Rfc3339());
0 ignored issues
show
Bug introduced by
The method Rfc3339() does not exist on SilverStripe\ORM\FieldType\DBField. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

233
        $this->assertEquals('2010-12-31T16:58:59+00:00', $date->/** @scrutinizer ignore-call */ Rfc3339());
Loading history...
234
    }
235
236
    /**
237
     * @param string $adjustment
238
     * @param string $expected
239
     * @dataProvider modifyProvider
240
     */
241
    public function testModify($adjustment, $expected)
242
    {
243
        DBDatetime::set_mock_now('2019-03-03 12:00:00');
244
        $result = DBDatetime::now()->modify($adjustment)->Rfc2822();
245
        $this->assertSame($expected, $result);
246
    }
247
248
    /**
249
     * @return array[]
250
     */
251
    public function modifyProvider()
252
    {
253
        return [
254
            ['+1 day', '2019-03-04 12:00:00'],
255
            ['-1 day', '2019-03-02 12:00:00'],
256
            ['+24 hours', '2019-03-04 12:00:00'],
257
            ['-24 hours', '2019-03-02 12:00:00'],
258
            ['+2 weeks', '2019-03-17 12:00:00'],
259
            ['-2 weeks', '2019-02-17 12:00:00'],
260
            ['+2 years', '2021-03-03 12:00:00'],
261
            ['-2 years', '2017-03-03 12:00:00'],
262
            ['+35 minutes', '2019-03-03 12:35:00'],
263
            ['-35 minutes', '2019-03-03 11:25:00'],
264
            ['+3 hours', '2019-03-03 15:00:00'],
265
            ['-3 hours', '2019-03-03 09:00:00'],
266
            ['+59 seconds', '2019-03-03 12:00:59'],
267
            ['-59 seconds', '2019-03-03 11:59:01'],
268
        ];
269
    }
270
}
271