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

DBDateTest::modifyProvider()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 9
nc 1
nop 0
dl 0
loc 11
rs 9.9666
c 0
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\DBDate;
8
use SilverStripe\ORM\FieldType\DBDatetime;
9
use SilverStripe\ORM\FieldType\DBField;
10
11
/**
12
 * @skipUpgrade
13
 */
14
class DBDateTest extends SapphireTest
15
{
16
    protected $oldError = null;
17
18
    protected function setUp()
19
    {
20
        parent::setUp();
21
        $this->oldError = error_reporting();
22
        // Validate setup
23
        assert(date_default_timezone_get() === 'UTC');
24
        i18n::set_locale('en_NZ');
25
    }
26
27
    protected function tearDown()
28
    {
29
        $this->restoreNotices();
30
        parent::tearDown();
31
    }
32
33
    /**
34
     * Temporarily disable notices
35
     */
36
    protected function suppressNotices()
37
    {
38
        error_reporting(error_reporting() & ~E_USER_NOTICE);
39
        \PHPUnit_Framework_Error_Notice::$enabled = false;
40
    }
41
42
    /**
43
     * Restore notices
44
     */
45
    protected function restoreNotices()
46
    {
47
        error_reporting($this->oldError);
48
        \PHPUnit_Framework_Error_Notice::$enabled = true;
49
    }
50
51
    public function testNiceDate()
52
    {
53
        $this->assertEquals(
54
            '31/03/2008',
55
            DBField::create_field('Date', 1206968400)->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

55
            DBField::create_field('Date', 1206968400)->/** @scrutinizer ignore-call */ Nice(),
Loading history...
56
            "Date->Nice() works with timestamp integers"
57
        );
58
        $this->assertEquals(
59
            '30/03/2008',
60
            DBField::create_field('Date', 1206882000)->Nice(),
61
            "Date->Nice() works with timestamp integers"
62
        );
63
        $this->assertEquals(
64
            '31/03/2008',
65
            DBField::create_field('Date', '1206968400')->Nice(),
66
            "Date->Nice() works with timestamp strings"
67
        );
68
        $this->assertEquals(
69
            '30/03/2008',
70
            DBField::create_field('Date', '1206882000')->Nice(),
71
            "Date->Nice() works with timestamp strings"
72
        );
73
        $this->assertEquals(
74
            '4/03/2003',
75
            DBField::create_field('Date', '4.3.2003')->Nice(),
76
            "Date->Nice() works with D.M.YYYY format"
77
        );
78
        $this->assertEquals(
79
            '4/03/2003',
80
            DBField::create_field('Date', '04.03.2003')->Nice(),
81
            "Date->Nice() works with DD.MM.YYYY format"
82
        );
83
        $this->assertEquals(
84
            '4/03/2003',
85
            DBField::create_field('Date', '2003-3-4')->Nice(),
86
            "Date->Nice() works with YYYY-M-D format"
87
        );
88
        $this->assertEquals(
89
            '4/03/2003',
90
            DBField::create_field('Date', '2003-03-04')->Nice(),
91
            "Date->Nice() works with YYYY-MM-DD format"
92
        );
93
    }
94
95
    /**
96
     * @expectedException \InvalidArgumentException
97
     * @expectedExceptionMessage Invalid date: '3/16/2003'. Use y-MM-dd to prevent this error.
98
     */
99
    public function testMDYConversion()
100
    {
101
        DBField::create_field('Date', '3/16/2003');
102
    }
103
104
    /**
105
     * @expectedException \InvalidArgumentException
106
     * @expectedExceptionMessage Invalid date: '03-03-04'. Use y-MM-dd to prevent this error.
107
     */
108
    public function testY2kCorrection()
109
    {
110
        DBField::create_field('Date', '03-03-04');
111
    }
112
113
    public function testInvertedYearCorrection()
114
    {
115
        // iso8601 expects year first, but support year last
116
        $this->assertEquals(
117
            '4/03/2003',
118
            DBField::create_field('Date', '04-03-2003')->Nice(),
119
            "Date->Nice() works with DD-MM-YYYY format"
120
        );
121
    }
122
123
    public function testYear()
124
    {
125
        $this->assertEquals(
126
            '2008',
127
            DBField::create_field('Date', 1206968400)->Year(),
0 ignored issues
show
Bug introduced by
The method Year() 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

127
            DBField::create_field('Date', 1206968400)->/** @scrutinizer ignore-call */ Year(),
Loading history...
128
            "Date->Year() works with timestamp integers"
129
        );
130
    }
131
132
    public function testDayOfWeek()
133
    {
134
        $this->assertEquals(
135
            'Monday',
136
            DBField::create_field('Date', 1206968400)->DayOfWeek(),
0 ignored issues
show
Bug introduced by
The method DayOfWeek() 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

136
            DBField::create_field('Date', 1206968400)->/** @scrutinizer ignore-call */ DayOfWeek(),
Loading history...
137
            "Date->Day() works with timestamp integers"
138
        );
139
    }
140
141
    public function testMonth()
142
    {
143
        $this->assertEquals(
144
            'March',
145
            DBField::create_field('Date', 1206968400)->Month(),
0 ignored issues
show
Bug introduced by
The method Month() 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
            DBField::create_field('Date', 1206968400)->/** @scrutinizer ignore-call */ Month(),
Loading history...
146
            "Date->Month() works with timestamp integers"
147
        );
148
    }
149
150
    public function testShortMonth()
151
    {
152
        $this->assertEquals(
153
            'Mar',
154
            DBField::create_field('Date', 1206968400)->ShortMonth(),
0 ignored issues
show
Bug introduced by
The method ShortMonth() 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

154
            DBField::create_field('Date', 1206968400)->/** @scrutinizer ignore-call */ ShortMonth(),
Loading history...
155
            "Date->ShortMonth() works with timestamp integers"
156
        );
157
    }
158
159
    public function testLongDate()
160
    {
161
        $this->assertEquals(
162
            '31 March 2008',
163
            DBField::create_field('Date', 1206968400)->Long(),
0 ignored issues
show
Bug introduced by
The method Long() 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

163
            DBField::create_field('Date', 1206968400)->/** @scrutinizer ignore-call */ Long(),
Loading history...
164
            "Date->Long() works with numeric timestamp"
165
        );
166
        $this->assertEquals(
167
            '31 March 2008',
168
            DBField::create_field('Date', '1206968400')->Long(),
169
            "Date->Long() works with string timestamp"
170
        );
171
        $this->assertEquals(
172
            '30 March 2008',
173
            DBField::create_field('Date', 1206882000)->Long(),
174
            "Date->Long() works with numeric timestamp"
175
        );
176
        $this->assertEquals(
177
            '30 March 2008',
178
            DBField::create_field('Date', '1206882000')->Long(),
179
            "Date->Long() works with numeric timestamp"
180
        );
181
        $this->assertEquals(
182
            '3 April 2003',
183
            DBField::create_field('Date', '2003-4-3')->Long(),
184
            "Date->Long() works with YYYY-M-D"
185
        );
186
        $this->assertEquals(
187
            '3 April 2003',
188
            DBField::create_field('Date', '3.4.2003')->Long(),
189
            "Date->Long() works with D.M.YYYY"
190
        );
191
    }
192
193
    public function testFull()
194
    {
195
        $this->assertEquals(
196
            'Monday, 31 March 2008',
197
            DBField::create_field('Date', 1206968400)->Full(),
0 ignored issues
show
Bug introduced by
The method Full() 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

197
            DBField::create_field('Date', 1206968400)->/** @scrutinizer ignore-call */ Full(),
Loading history...
198
            "Date->Full() works with timestamp integers"
199
        );
200
    }
201
202
    public function testSetNullAndZeroValues()
203
    {
204
        $date = DBField::create_field('Date', '');
205
        $this->assertNull($date->getValue(), 'Empty string evaluates to NULL');
206
207
        $date = DBField::create_field('Date', null);
208
        $this->assertNull($date->getValue(), 'NULL is set as NULL');
209
210
        $date = DBField::create_field('Date', false);
211
        $this->assertNull($date->getValue(), 'Boolean FALSE evaluates to NULL');
212
213
        $date = DBField::create_field('Date', array());
214
        $this->assertNull($date->getValue(), 'Empty array evaluates to NULL');
215
216
        $date = DBField::create_field('Date', '0');
217
        $this->assertEquals('1970-01-01', $date->getValue(), 'Zero is UNIX epoch date');
218
219
        $date = DBField::create_field('Date', 0);
220
        $this->assertEquals('1970-01-01', $date->getValue(), 'Zero is UNIX epoch date');
221
222
        $date = DBField::create_field('Date', '0000-00-00 00:00:00');
223
        $this->assertNull($date->getValue(), '0000-00-00 00:00:00 is set as NULL');
224
225
        $date = DBField::create_field('Date', '00/00/0000');
226
        $this->assertNull($date->getValue(), '00/00/0000 is set as NULL');
227
    }
228
229
    public function testDayOfMonth()
230
    {
231
        $date = DBField::create_field('Date', '2000-10-10');
232
        $this->assertEquals('10', $date->DayOfMonth());
0 ignored issues
show
Bug introduced by
The method DayOfMonth() 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

232
        $this->assertEquals('10', $date->/** @scrutinizer ignore-call */ DayOfMonth());
Loading history...
233
        $this->assertEquals('10th', $date->DayOfMonth(true));
234
235
        $range = $date->RangeString(DBField::create_field('Date', '2000-10-20'));
0 ignored issues
show
Bug introduced by
The method RangeString() 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

235
        /** @scrutinizer ignore-call */ 
236
        $range = $date->RangeString(DBField::create_field('Date', '2000-10-20'));
Loading history...
236
        $this->assertEquals('10 - 20 Oct 2000', $range);
237
        $range = $date->RangeString(DBField::create_field('Date', '2000-10-20'), true);
238
        $this->assertEquals('10th - 20th Oct 2000', $range);
239
    }
240
241
    public function testFormatReplacesOrdinals()
242
    {
243
        $this->assertEquals(
244
            '20th October 2000',
245
            DBField::create_field('Date', '2000-10-20')->Format('{o} MMMM YYYY'),
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

245
            DBField::create_field('Date', '2000-10-20')->/** @scrutinizer ignore-call */ Format('{o} MMMM YYYY'),
Loading history...
246
            'Ordinal day of month was not injected'
247
        );
248
249
        $this->assertEquals(
250
            '20th is the 20th day of the month',
251
            DBField::create_field('Date', '2000-10-20')->Format("{o} 'is the' {o} 'day of the month'"),
252
            'Failed to inject multiple ordinal values into one string'
253
        );
254
    }
255
256
    public function testExtendedDates()
257
    {
258
        $date = DBField::create_field('Date', '1800-10-10');
259
        $this->assertEquals('10 Oct 1800', $date->Format('dd MMM y'));
260
261
        // Note: Fails around 1500 or older
262
        $date = DBField::create_field('Date', '1600-10-10');
263
        $this->assertEquals('10 Oct 1600', $date->Format('dd MMM y'));
264
265
        $date = DBField::create_field('Date', '3000-4-3');
266
        $this->assertEquals('03 Apr 3000', $date->Format('dd MMM y'));
267
    }
268
269
    public function testAgoInPast()
270
    {
271
        DBDatetime::set_mock_now('2000-12-31 12:00:00');
272
273
        $this->assertEquals(
274
            '1 month ago',
275
            DBField::create_field('Date', '2000-11-26')->Ago(true, 1),
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

275
            DBField::create_field('Date', '2000-11-26')->/** @scrutinizer ignore-call */ Ago(true, 1),
Loading history...
276
            'Past match on days, less than two months, lowest significance'
277
        );
278
279
        $this->assertEquals(
280
            '50 days ago', // Rounded from 49.5 days up
281
            DBField::create_field('Date', '2000-11-12')->Ago(),
282
            'Past match on days, less than two months'
283
        );
284
285
        $this->assertEquals(
286
            '2 months ago',
287
            DBField::create_field('Date', '2000-10-27')->Ago(),
288
            'Past match on days, over two months'
289
        );
290
291
        $this->assertEquals(
292
            '66 days ago', // rounded from 65.5 days up
293
            DBField::create_field('Date', '2000-10-27')->Ago(true, 3),
294
            'Past match on days, over two months, significance of 3'
295
        );
296
297
        $this->assertEquals(
298
            '10 years ago',
299
            DBField::create_field('Date', '1990-12-31')->Ago(),
300
            'Exact past match on years'
301
        );
302
303
        $this->assertEquals(
304
            '10 years ago',
305
            DBField::create_field('Date', '1990-12-30')->Ago(),
306
            'Approximate past match on years'
307
        );
308
309
        $this->assertEquals(
310
            '1 year ago',
311
            DBField::create_field('Date', '1999-12-30')->Ago(true, 1),
312
            'Approximate past match in singular, lowest significance'
313
        );
314
315
        $this->assertEquals(
316
            '12 months ago',
317
            DBField::create_field('Date', '1999-12-30')->Ago(),
318
            'Approximate past match in singular'
319
        );
320
321
        DBDatetime::clear_mock_now();
322
    }
323
324
    public function testAgoInFuture()
325
    {
326
        DBDatetime::set_mock_now('2000-12-31 00:00:00');
327
328
        $this->assertEquals(
329
            'in 10 years',
330
            DBField::create_field('Date', '2010-12-31')->Ago(),
331
            'Exact past match on years'
332
        );
333
334
        $this->assertEquals(
335
            'in 1 day',
336
            DBField::create_field('Date', '2001-01-01')->Ago(true, 1),
337
            'Approximate past match on minutes'
338
        );
339
340
        $this->assertEquals(
341
            'in 24 hours',
342
            DBField::create_field('Date', '2001-01-01')->Ago(),
343
            'Approximate past match on minutes'
344
        );
345
346
        DBDatetime::clear_mock_now();
347
    }
348
349
    public function testRfc3999()
350
    {
351
        // Dates should be formatted as: 2018-01-24T14:05:53+00:00
352
        $date = DBDate::create_field('Date', '2010-12-31');
353
        $this->assertEquals('2010-12-31T00:00:00+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

353
        $this->assertEquals('2010-12-31T00:00:00+00:00', $date->/** @scrutinizer ignore-call */ Rfc3339());
Loading history...
354
    }
355
356
    /**
357
     * @param string $adjustment
358
     * @param string $expected
359
     * @dataProvider modifyProvider
360
     */
361
    public function testModify($adjustment, $expected)
362
    {
363
        /** @var DBDate $dateField */
364
        $dateField = DBField::create_field('Date', '2019-03-03');
365
        $result = $dateField->modify($adjustment)->URLDate();
366
        $this->assertSame($expected, $result);
367
    }
368
369
    /**
370
     * @return array[]
371
     */
372
    public function modifyProvider()
373
    {
374
        return [
375
            ['+1 day', '2019-03-04'],
376
            ['-1 day', '2019-03-02'],
377
            ['+24 hours', '2019-03-04'],
378
            ['-24 hours', '2019-03-02'],
379
            ['+2 weeks', '2019-03-17'],
380
            ['-2 weeks', '2019-02-17'],
381
            ['+2 years', '2021-03-03'],
382
            ['-2 years', '2017-03-03'],
383
        ];
384
    }
385
}
386