Passed
Push — 4 ( 9d73b7...2cf172 )
by Guy
06:54 queued 12s
created

DBDatetimeTest::testMockSleep()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 1
eloc 11
c 2
b 1
f 0
nc 1
nop 0
dl 0
loc 16
rs 9.9
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(): void
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 testFixedNow()
46
    {
47
        $mockDate1 = '2010-01-01 10:00:00';
48
        $mockDate2 = '2011-01-01 10:00:00';
49
50
        DBDatetime::withFixedNow($mockDate1, function () use ($mockDate1, $mockDate2) {
51
            $this->assertEquals($mockDate1, DBDatetime::now()->Rfc2822());
52
53
            DBDatetime::withFixedNow($mockDate2, function () use ($mockDate2) {
54
                $this->assertEquals($mockDate2, DBDatetime::now()->Rfc2822());
55
            });
56
57
            $this->assertEquals($mockDate1, DBDatetime::now()->Rfc2822());
58
        });
59
    }
60
61
    public function testMockSleep()
62
    {
63
        DBDatetime::set_mock_now('2010-01-01 10:00:00');
64
65
        $this->mockSleep(1);
66
        $this->assertEquals(
67
            '2010-01-01 10:00:01',
68
            DBDatetime::now()->Rfc2822(),
69
            'We expect the time to move forward by 1 second'
70
        );
71
72
        $this->mockSleep(10);
73
        $this->assertEquals(
74
            '2010-01-01 10:00:11',
75
            DBDatetime::now()->Rfc2822(),
76
            'We expect the time to move forward by 10 seconds'
77
        );
78
    }
79
80
    public function testSetNullAndZeroValues()
81
    {
82
        $date = DBDatetime::create_field('Datetime', '');
83
        $this->assertNull($date->getValue(), 'Empty string evaluates to NULL');
84
85
        $date = DBDatetime::create_field('Datetime', null);
86
        $this->assertNull($date->getValue(), 'NULL is set as NULL');
87
88
        $date = DBDatetime::create_field('Datetime', false);
89
        $this->assertNull($date->getValue(), 'Boolean FALSE evaluates to NULL');
90
91
        $date = DBDatetime::create_field('Datetime', '0');
92
        $this->assertEquals('1970-01-01 00:00:00', $date->getValue(), 'String zero is UNIX epoch time');
93
94
        $date = DBDatetime::create_field('Datetime', 0);
95
        $this->assertEquals('1970-01-01 00:00:00', $date->getValue(), 'Numeric zero is UNIX epoch time');
96
    }
97
98
    public function testExtendedDateTimes()
99
    {
100
        $date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
101
        $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

101
        $this->assertEquals('10 Oct 1600 15 32 24', $date->/** @scrutinizer ignore-call */ Format('d MMM y H m s'));
Loading history...
102
103
        $date = DBDatetime::create_field('Datetime', '3000-10-10 15:32:24');
104
        $this->assertEquals('10 Oct 3000 15 32 24', $date->Format('d MMM y H m s'));
105
    }
106
107
    /**
108
     * Coverage for dates using hindi-numerals
109
     */
110
    public function testHindiNumerals()
111
    {
112
        // Parent locale is english; Can be localised to arabic
113
        $date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
114
        $this->assertEquals('10 Oct 1600 15 32 24', $date->Format('d MMM y H m s'));
115
        $this->assertEquals('١٠ أكتوبر ١٦٠٠ ١٥ ٣٢ ٢٤', $date->Format('d MMM y H m s', 'ar'));
116
117
        // Parent locale is arabic; Datavalue uses ISO date
118
        i18n::set_locale('ar');
119
        $date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
120
        $this->assertEquals('١٠ أكتوبر ١٦٠٠ ١٥ ٣٢ ٢٤', $date->Format('d MMM y H m s'));
121
        $this->assertEquals('1600-10-10 15:32:24', $date->getValue());
122
    }
123
124
    public function testNice()
125
    {
126
        $date = DBDatetime::create_field('Datetime', '2001-12-11 22:10:59');
127
128
        // note: Some localisation packages exclude the ',' in default medium format
129
        i18n::set_locale('en_NZ');
130
        $this->assertMatchesRegularExpression('#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

130
        $this->assertMatchesRegularExpression('#11/12/2001(,)? 10:10 PM#i', $date->/** @scrutinizer ignore-call */ Nice());
Loading history...
131
132
        i18n::set_locale('en_US');
133
        $this->assertMatchesRegularExpression('#Dec 11(,)? 2001(,)? 10:10 PM#i', $date->Nice());
134
    }
135
136
    public function testDate()
137
    {
138
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
139
        $this->assertEquals('31/12/2001', $date->Date());
140
    }
141
142
    public function testTime()
143
    {
144
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
145
        $this->assertMatchesRegularExpression('#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

145
        $this->assertMatchesRegularExpression('#10:10:59 PM#i', $date->/** @scrutinizer ignore-call */ Time());
Loading history...
146
    }
147
148
    public function testTime24()
149
    {
150
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
151
        $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

151
        $this->assertEquals('22:10', $date->/** @scrutinizer ignore-call */ Time24());
Loading history...
152
    }
153
154
    public function testURLDateTime()
155
    {
156
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
157
        $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

157
        $this->assertEquals('2001-12-31%2022%3A10%3A59', $date->/** @scrutinizer ignore-call */ URLDateTime());
Loading history...
158
    }
159
160
    public function testAgoInPast()
161
    {
162
        DBDatetime::set_mock_now('2000-12-31 12:00:00');
163
164
        $this->assertEquals(
165
            '10 years ago',
166
            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

166
            DBDatetime::create_field('Datetime', '1990-12-31 12:00:00')->/** @scrutinizer ignore-call */ Ago(),
Loading history...
167
            'Exact past match on years'
168
        );
169
170
        $this->assertEquals(
171
            '10 years ago',
172
            DBDatetime::create_field('Datetime', '1990-12-30 12:00:00')->Ago(),
173
            'Approximate past match on years'
174
        );
175
176
        $this->assertEquals(
177
            '1 year ago',
178
            DBDatetime::create_field('Datetime', '1999-12-30 12:00:12')->Ago(true, 1),
179
            'Approximate past match in singular, significance=1'
180
        );
181
182
        $this->assertEquals(
183
            '12 months ago',
184
            DBDatetime::create_field('Datetime', '1999-12-30 12:00:12')->Ago(),
185
            'Approximate past match in singular'
186
        );
187
188
        $this->assertEquals(
189
            '50 mins ago',
190
            DBDatetime::create_field('Datetime', '2000-12-31 11:10:11')->Ago(),
191
            'Approximate past match on minutes'
192
        );
193
194
        $this->assertEquals(
195
            '59 secs ago',
196
            DBDatetime::create_field('Datetime', '2000-12-31 11:59:01')->Ago(),
197
            'Approximate past match on seconds'
198
        );
199
200
        $this->assertEquals(
201
            'less than a minute ago',
202
            DBDatetime::create_field('Datetime', '2000-12-31 11:59:01')->Ago(false),
203
            'Approximate past match on seconds with $includeSeconds=false'
204
        );
205
206
        $this->assertEquals(
207
            '1 min ago',
208
            DBDatetime::create_field('Datetime', '2000-12-31 11:58:50')->Ago(false),
209
            'Test between 1 and 2 minutes with includeSeconds=false'
210
        );
211
212
        $this->assertEquals(
213
            '70 secs ago',
214
            DBDatetime::create_field('Datetime', '2000-12-31 11:58:50')->Ago(true),
215
            'Test between 1 and 2 minutes with includeSeconds=true'
216
        );
217
218
        $this->assertEquals(
219
            '4 mins ago',
220
            DBDatetime::create_field('Datetime', '2000-12-31 11:55:50')->Ago(),
221
            'Past match on minutes'
222
        );
223
224
        $this->assertEquals(
225
            '1 hour ago',
226
            DBDatetime::create_field('Datetime', '2000-12-31 10:50:58')->Ago(true, 1),
227
            'Past match on hours, significance=1'
228
        );
229
230
        $this->assertEquals(
231
            '3 hours ago',
232
            DBDatetime::create_field('Datetime', '2000-12-31 08:50:58')->Ago(),
233
            'Past match on hours'
234
        );
235
236
        DBDatetime::clear_mock_now();
237
    }
238
239
    public function testAgoInFuture()
240
    {
241
        DBDatetime::set_mock_now('2000-12-31 00:00:00');
242
243
        $this->assertEquals(
244
            'in 10 years',
245
            DBDatetime::create_field('Datetime', '2010-12-31 12:00:00')->Ago(),
246
            'Exact past match on years'
247
        );
248
249
        $this->assertEquals(
250
            'in 1 hour',
251
            DBDatetime::create_field('Datetime', '2000-12-31 1:01:05')->Ago(true, 1),
252
            'Approximate past match on minutes, significance=1'
253
        );
254
255
        $this->assertEquals(
256
            'in 61 mins',
257
            DBDatetime::create_field('Datetime', '2000-12-31 1:01:05')->Ago(),
258
            'Approximate past match on minutes'
259
        );
260
261
        DBDatetime::clear_mock_now();
262
    }
263
264
    public function testRfc3999()
265
    {
266
        // Dates should be formatted as: 2018-01-24T14:05:53+00:00
267
        $date = DBDatetime::create_field('Datetime', '2010-12-31 16:58:59');
268
        $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

268
        $this->assertEquals('2010-12-31T16:58:59+00:00', $date->/** @scrutinizer ignore-call */ Rfc3339());
Loading history...
269
    }
270
271
    /**
272
     * @param string $adjustment
273
     * @param string $expected
274
     * @dataProvider modifyProvider
275
     */
276
    public function testModify($adjustment, $expected)
277
    {
278
        DBDatetime::set_mock_now('2019-03-03 12:00:00');
279
        $result = DBDatetime::now()->modify($adjustment)->Rfc2822();
280
        $this->assertSame($expected, $result);
281
    }
282
283
    /**
284
     * @return array[]
285
     */
286
    public function modifyProvider()
287
    {
288
        return [
289
            ['+1 day', '2019-03-04 12:00:00'],
290
            ['-1 day', '2019-03-02 12:00:00'],
291
            ['+24 hours', '2019-03-04 12:00:00'],
292
            ['-24 hours', '2019-03-02 12:00:00'],
293
            ['+2 weeks', '2019-03-17 12:00:00'],
294
            ['-2 weeks', '2019-02-17 12:00:00'],
295
            ['+2 years', '2021-03-03 12:00:00'],
296
            ['-2 years', '2017-03-03 12:00:00'],
297
            ['+35 minutes', '2019-03-03 12:35:00'],
298
            ['-35 minutes', '2019-03-03 11:25:00'],
299
            ['+3 hours', '2019-03-03 15:00:00'],
300
            ['-3 hours', '2019-03-03 09:00:00'],
301
            ['+59 seconds', '2019-03-03 12:00:59'],
302
            ['-59 seconds', '2019-03-03 11:59:01'],
303
        ];
304
    }
305
}
306