Passed
Push — fix-9163 ( 4cfde3...07a516 )
by Ingo
17:14
created

DBDatetimeTest::testFixedNow()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 7
nc 1
nop 0
dl 0
loc 13
rs 10
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 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 testSetNullAndZeroValues()
62
    {
63
        $date = DBDatetime::create_field('Datetime', '');
64
        $this->assertNull($date->getValue(), 'Empty string evaluates to NULL');
65
66
        $date = DBDatetime::create_field('Datetime', null);
67
        $this->assertNull($date->getValue(), 'NULL is set as NULL');
68
69
        $date = DBDatetime::create_field('Datetime', false);
70
        $this->assertNull($date->getValue(), 'Boolean FALSE evaluates to NULL');
71
72
        $date = DBDatetime::create_field('Datetime', '0');
73
        $this->assertEquals('1970-01-01 00:00:00', $date->getValue(), 'String zero is UNIX epoch time');
74
75
        $date = DBDatetime::create_field('Datetime', 0);
76
        $this->assertEquals('1970-01-01 00:00:00', $date->getValue(), 'Numeric zero is UNIX epoch time');
77
    }
78
79
    public function testExtendedDateTimes()
80
    {
81
        $date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
82
        $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

82
        $this->assertEquals('10 Oct 1600 15 32 24', $date->/** @scrutinizer ignore-call */ Format('d MMM y H m s'));
Loading history...
83
84
        $date = DBDatetime::create_field('Datetime', '3000-10-10 15:32:24');
85
        $this->assertEquals('10 Oct 3000 15 32 24', $date->Format('d MMM y H m s'));
86
    }
87
88
    /**
89
     * Coverage for dates using hindi-numerals
90
     */
91
    public function testHindiNumerals()
92
    {
93
        // Parent locale is english; Can be localised to arabic
94
        $date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
95
        $this->assertEquals('10 Oct 1600 15 32 24', $date->Format('d MMM y H m s'));
96
        $this->assertEquals('١٠ أكتوبر ١٦٠٠ ١٥ ٣٢ ٢٤', $date->Format('d MMM y H m s', 'ar'));
97
98
        // Parent locale is arabic; Datavalue uses ISO date
99
        i18n::set_locale('ar');
100
        $date = DBDatetime::create_field('Datetime', '1600-10-10 15:32:24');
101
        $this->assertEquals('١٠ أكتوبر ١٦٠٠ ١٥ ٣٢ ٢٤', $date->Format('d MMM y H m s'));
102
        $this->assertEquals('1600-10-10 15:32:24', $date->getValue());
103
    }
104
105
    public function testNice()
106
    {
107
        $date = DBDatetime::create_field('Datetime', '2001-12-11 22:10:59');
108
109
        // note: Some localisation packages exclude the ',' in default medium format
110
        i18n::set_locale('en_NZ');
111
        $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

111
        $this->assertRegExp('#11/12/2001(,)? 10:10 PM#i', $date->/** @scrutinizer ignore-call */ Nice());
Loading history...
112
113
        i18n::set_locale('en_US');
114
        $this->assertRegExp('#Dec 11(,)? 2001(,)? 10:10 PM#i', $date->Nice());
115
    }
116
117
    public function testDate()
118
    {
119
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
120
        $this->assertEquals('31/12/2001', $date->Date());
121
    }
122
123
    public function testTime()
124
    {
125
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
126
        $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

126
        $this->assertRegexp('#10:10:59 PM#i', $date->/** @scrutinizer ignore-call */ Time());
Loading history...
127
    }
128
129
    public function testTime24()
130
    {
131
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
132
        $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

132
        $this->assertEquals('22:10', $date->/** @scrutinizer ignore-call */ Time24());
Loading history...
133
    }
134
135
    public function testURLDateTime()
136
    {
137
        $date = DBDatetime::create_field('Datetime', '2001-12-31 22:10:59');
138
        $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

138
        $this->assertEquals('2001-12-31%2022%3A10%3A59', $date->/** @scrutinizer ignore-call */ URLDateTime());
Loading history...
139
    }
140
141
    public function testAgoInPast()
142
    {
143
        DBDatetime::set_mock_now('2000-12-31 12:00:00');
144
145
        $this->assertEquals(
146
            '10 years ago',
147
            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

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

249
        $this->assertEquals('2010-12-31T16:58:59+00:00', $date->/** @scrutinizer ignore-call */ Rfc3339());
Loading history...
250
    }
251
252
    /**
253
     * @param string $adjustment
254
     * @param string $expected
255
     * @dataProvider modifyProvider
256
     */
257
    public function testModify($adjustment, $expected)
258
    {
259
        DBDatetime::set_mock_now('2019-03-03 12:00:00');
260
        $result = DBDatetime::now()->modify($adjustment)->Rfc2822();
261
        $this->assertSame($expected, $result);
262
    }
263
264
    /**
265
     * @return array[]
266
     */
267
    public function modifyProvider()
268
    {
269
        return [
270
            ['+1 day', '2019-03-04 12:00:00'],
271
            ['-1 day', '2019-03-02 12:00:00'],
272
            ['+24 hours', '2019-03-04 12:00:00'],
273
            ['-24 hours', '2019-03-02 12:00:00'],
274
            ['+2 weeks', '2019-03-17 12:00:00'],
275
            ['-2 weeks', '2019-02-17 12:00:00'],
276
            ['+2 years', '2021-03-03 12:00:00'],
277
            ['-2 years', '2017-03-03 12:00:00'],
278
            ['+35 minutes', '2019-03-03 12:35:00'],
279
            ['-35 minutes', '2019-03-03 11:25:00'],
280
            ['+3 hours', '2019-03-03 15:00:00'],
281
            ['-3 hours', '2019-03-03 09:00:00'],
282
            ['+59 seconds', '2019-03-03 12:00:59'],
283
            ['-59 seconds', '2019-03-03 11:59:01'],
284
        ];
285
    }
286
}
287