Mercurial > hg > isophonics-drupal-site
comparison core/tests/Drupal/Tests/Component/Datetime/DateTimePlusTest.php @ 0:4c8ae668cc8c
Initial import (non-working)
author | Chris Cannam |
---|---|
date | Wed, 29 Nov 2017 16:09:58 +0000 |
parents | |
children | 7a779792577d |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:4c8ae668cc8c |
---|---|
1 <?php | |
2 | |
3 namespace Drupal\Tests\Component\Datetime; | |
4 | |
5 use Drupal\Component\Datetime\DateTimePlus; | |
6 use PHPUnit\Framework\TestCase; | |
7 | |
8 /** | |
9 * @coversDefaultClass \Drupal\Component\Datetime\DateTimePlus | |
10 * @group Datetime | |
11 */ | |
12 class DateTimePlusTest extends TestCase { | |
13 | |
14 /** | |
15 * Test creating dates from string and array input. | |
16 * | |
17 * @param mixed $input | |
18 * Input argument for DateTimePlus. | |
19 * @param string $timezone | |
20 * Timezone argument for DateTimePlus. | |
21 * @param string $expected | |
22 * Expected output from DateTimePlus::format(). | |
23 * | |
24 * @dataProvider providerTestDates | |
25 */ | |
26 public function testDates($input, $timezone, $expected) { | |
27 $date = new DateTimePlus($input, $timezone); | |
28 $value = $date->format('c'); | |
29 | |
30 if (is_array($input)) { | |
31 $input = var_export($input, TRUE); | |
32 } | |
33 $this->assertEquals($expected, $value, sprintf("Test new DateTimePlus(%s, %s): should be %s, found %s.", $input, $timezone, $expected, $value)); | |
34 } | |
35 | |
36 /** | |
37 * Test creating dates from string and array input. | |
38 * | |
39 * @param mixed $input | |
40 * Input argument for DateTimePlus. | |
41 * @param string $timezone | |
42 * Timezone argument for DateTimePlus. | |
43 * @param string $expected | |
44 * Expected output from DateTimePlus::format(). | |
45 * | |
46 * @dataProvider providerTestDateArrays | |
47 */ | |
48 public function testDateArrays($input, $timezone, $expected) { | |
49 $date = DateTimePlus::createFromArray($input, $timezone); | |
50 $value = $date->format('c'); | |
51 | |
52 if (is_array($input)) { | |
53 $input = var_export($input, TRUE); | |
54 } | |
55 $this->assertEquals($expected, $value, sprintf("Test new DateTimePlus(%s, %s): should be %s, found %s.", $input, $timezone, $expected, $value)); | |
56 } | |
57 | |
58 /** | |
59 * Test date diffs. | |
60 * | |
61 * @param mixed $input1 | |
62 * A DateTimePlus object. | |
63 * @param mixed $input2 | |
64 * Date argument for DateTimePlus::diff method. | |
65 * @param bool $absolute | |
66 * Absolute flag for DateTimePlus::diff method. | |
67 * @param \DateInterval $expected | |
68 * The expected result of the DateTimePlus::diff operation. | |
69 * | |
70 * @dataProvider providerTestDateDiff | |
71 */ | |
72 public function testDateDiff($input1, $input2, $absolute, \DateInterval $expected) { | |
73 $interval = $input1->diff($input2, $absolute); | |
74 $this->assertEquals($interval, $expected); | |
75 } | |
76 | |
77 /** | |
78 * Test date diff exception caused by invalid input. | |
79 * | |
80 * @param mixed $input1 | |
81 * A DateTimePlus object. | |
82 * @param mixed $input2 | |
83 * Date argument for DateTimePlus::diff method. | |
84 * @param bool $absolute | |
85 * Absolute flag for DateTimePlus::diff method. | |
86 * | |
87 * @dataProvider providerTestInvalidDateDiff | |
88 */ | |
89 public function testInvalidDateDiff($input1, $input2, $absolute) { | |
90 $this->setExpectedException(\BadMethodCallException::class, 'Method Drupal\Component\Datetime\DateTimePlus::diff expects parameter 1 to be a \DateTime or \Drupal\Component\Datetime\DateTimePlus object'); | |
91 $interval = $input1->diff($input2, $absolute); | |
92 } | |
93 | |
94 /** | |
95 * Test creating dates from invalid array input. | |
96 * | |
97 * @param mixed $input | |
98 * Input argument for DateTimePlus. | |
99 * @param string $timezone | |
100 * Timezone argument for DateTimePlus. | |
101 * @param string $class | |
102 * The Exception subclass to expect to be thrown. | |
103 * | |
104 * @dataProvider providerTestInvalidDateArrays | |
105 */ | |
106 public function testInvalidDateArrays($input, $timezone, $class) { | |
107 $this->setExpectedException($class); | |
108 $this->assertInstanceOf( | |
109 '\Drupal\Component\DateTimePlus', | |
110 DateTimePlus::createFromArray($input, $timezone) | |
111 ); | |
112 } | |
113 | |
114 /** | |
115 * Test creating dates from timestamps, and manipulating timezones. | |
116 * | |
117 * @param int $input | |
118 * Input argument for DateTimePlus::createFromTimestamp(). | |
119 * @param array $initial | |
120 * An array containing: | |
121 * - 'timezone_initial' - Timezone argument for DateTimePlus. | |
122 * - 'format_initial' - Format argument for DateTimePlus. | |
123 * - 'expected_initial_date' - Expected output from DateTimePlus::format(). | |
124 * - 'expected_initial_timezone' - Expected output from | |
125 * DateTimePlus::getTimeZone()::getName(). | |
126 * - 'expected_initial_offset' - Expected output from DateTimePlus::getOffset(). | |
127 * @param array $transform | |
128 * An array containing: | |
129 * - 'timezone_transform' - Argument to transform date to another timezone via | |
130 * DateTimePlus::setTimezone(). | |
131 * - 'format_transform' - Format argument to use when transforming date to | |
132 * another timezone. | |
133 * - 'expected_transform_date' - Expected output from DateTimePlus::format(), | |
134 * after timezone transform. | |
135 * - 'expected_transform_timezone' - Expected output from | |
136 * DateTimePlus::getTimeZone()::getName(), after timezone transform. | |
137 * - 'expected_transform_offset' - Expected output from | |
138 * DateTimePlus::getOffset(), after timezone transform. | |
139 * | |
140 * @dataProvider providerTestTimestamp | |
141 */ | |
142 public function testTimestamp($input, array $initial, array $transform) { | |
143 // Initialize a new date object. | |
144 $date = DateTimePlus::createFromTimestamp($input, $initial['timezone']); | |
145 $this->assertDateTimestamp($date, $input, $initial, $transform); | |
146 } | |
147 | |
148 /** | |
149 * Test creating dates from datetime strings. | |
150 * | |
151 * @param string $input | |
152 * Input argument for DateTimePlus(). | |
153 * @param array $initial | |
154 * @see testTimestamp() | |
155 * @param array $transform | |
156 * @see testTimestamp() | |
157 * | |
158 * @dataProvider providerTestDateTimestamp | |
159 */ | |
160 public function testDateTimestamp($input, array $initial, array $transform) { | |
161 // Initialize a new date object. | |
162 $date = new DateTimePlus($input, $initial['timezone']); | |
163 $this->assertDateTimestamp($date, $input, $initial, $transform); | |
164 } | |
165 | |
166 /** | |
167 * Assertion helper for testTimestamp and testDateTimestamp since they need | |
168 * different dataProviders. | |
169 * | |
170 * @param DateTimePlus $date | |
171 * DateTimePlus to test. | |
172 * @input mixed $input | |
173 * The original input passed to the test method. | |
174 * @param array $initial | |
175 * @see testTimestamp() | |
176 * @param array $transform | |
177 * @see testTimestamp() | |
178 */ | |
179 public function assertDateTimestamp($date, $input, $initial, $transform) { | |
180 // Check format. | |
181 $value = $date->format($initial['format']); | |
182 $this->assertEquals($initial['expected_date'], $value, sprintf("Test new DateTimePlus(%s, %s): should be %s, found %s.", $input, $initial['timezone'], $initial['expected_date'], $value)); | |
183 | |
184 // Check timezone name. | |
185 $value = $date->getTimeZone()->getName(); | |
186 $this->assertEquals($initial['expected_timezone'], $value, sprintf("The current timezone is %s: should be %s.", $value, $initial['expected_timezone'])); | |
187 | |
188 // Check offset. | |
189 $value = $date->getOffset(); | |
190 $this->assertEquals($initial['expected_offset'], $value, sprintf("The current offset is %s: should be %s.", $value, $initial['expected_offset'])); | |
191 | |
192 // Transform the date to another timezone. | |
193 $date->setTimezone(new \DateTimeZone($transform['timezone'])); | |
194 | |
195 // Check transformed format. | |
196 $value = $date->format($transform['format']); | |
197 $this->assertEquals($transform['expected_date'], $value, sprintf("Test \$date->setTimezone(new \\DateTimeZone(%s)): should be %s, found %s.", $transform['timezone'], $transform['expected_date'], $value)); | |
198 | |
199 // Check transformed timezone. | |
200 $value = $date->getTimeZone()->getName(); | |
201 $this->assertEquals($transform['expected_timezone'], $value, sprintf("The current timezone should be %s, found %s.", $transform['expected_timezone'], $value)); | |
202 | |
203 // Check transformed offset. | |
204 $value = $date->getOffset(); | |
205 $this->assertEquals($transform['expected_offset'], $value, sprintf("The current offset should be %s, found %s.", $transform['expected_offset'], $value)); | |
206 } | |
207 | |
208 /** | |
209 * Test creating dates from format strings. | |
210 * | |
211 * @param string $input | |
212 * Input argument for DateTimePlus. | |
213 * @param string $timezone | |
214 * Timezone argument for DateTimePlus. | |
215 * @param string $format_date | |
216 * Format argument for DateTimePlus::format(). | |
217 * @param string $expected | |
218 * Expected output from DateTimePlus::format(). | |
219 * | |
220 * @dataProvider providerTestDateFormat | |
221 */ | |
222 public function testDateFormat($input, $timezone, $format, $format_date, $expected) { | |
223 $date = DateTimePlus::createFromFormat($format, $input, $timezone); | |
224 $value = $date->format($format_date); | |
225 $this->assertEquals($expected, $value, sprintf("Test new DateTimePlus(%s, %s, %s): should be %s, found %s.", $input, $timezone, $format, $expected, $value)); | |
226 } | |
227 | |
228 /** | |
229 * Test invalid date handling. | |
230 * | |
231 * @param mixed $input | |
232 * Input argument for DateTimePlus. | |
233 * @param string $timezone | |
234 * Timezone argument for DateTimePlus. | |
235 * @param string $format | |
236 * Format argument for DateTimePlus. | |
237 * @param string $message | |
238 * Message to print if no errors are thrown by the invalid dates. | |
239 * @param string $class | |
240 * The Exception subclass to expect to be thrown. | |
241 * | |
242 * @dataProvider providerTestInvalidDates | |
243 */ | |
244 public function testInvalidDates($input, $timezone, $format, $message, $class) { | |
245 $this->setExpectedException($class); | |
246 DateTimePlus::createFromFormat($format, $input, $timezone); | |
247 } | |
248 | |
249 /** | |
250 * Tests that DrupalDateTime can detect the right timezone to use. | |
251 * When specified or not. | |
252 * | |
253 * @param mixed $input | |
254 * Input argument for DateTimePlus. | |
255 * @param mixed $timezone | |
256 * Timezone argument for DateTimePlus. | |
257 * @param string $expected_timezone | |
258 * Expected timezone returned from DateTimePlus::getTimezone::getName(). | |
259 * @param string $message | |
260 * Message to print on test failure. | |
261 * | |
262 * @dataProvider providerTestDateTimezone | |
263 */ | |
264 public function testDateTimezone($input, $timezone, $expected_timezone, $message) { | |
265 $date = new DateTimePlus($input, $timezone); | |
266 $timezone = $date->getTimezone()->getName(); | |
267 $this->assertEquals($timezone, $expected_timezone, $message); | |
268 } | |
269 | |
270 /** | |
271 * Test that DrupalDateTime can detect the right timezone to use when | |
272 * constructed from a datetime object. | |
273 */ | |
274 public function testDateTimezoneWithDateTimeObject() { | |
275 // Create a date object with another date object. | |
276 $input = new \DateTime('now', new \DateTimeZone('Pacific/Midway')); | |
277 $timezone = NULL; | |
278 $expected_timezone = 'Pacific/Midway'; | |
279 $message = 'DateTimePlus uses the specified timezone if provided.'; | |
280 | |
281 $date = DateTimePlus::createFromDateTime($input, $timezone); | |
282 $timezone = $date->getTimezone()->getName(); | |
283 $this->assertEquals($timezone, $expected_timezone, $message); | |
284 } | |
285 | |
286 /** | |
287 * Provides data for date tests. | |
288 * | |
289 * @return array | |
290 * An array of arrays, each containing the input parameters for | |
291 * DateTimePlusTest::testDates(). | |
292 * | |
293 * @see DateTimePlusTest::testDates() | |
294 */ | |
295 public function providerTestDates() { | |
296 $dates = [ | |
297 // String input. | |
298 // Create date object from datetime string. | |
299 ['2009-03-07 10:30', 'America/Chicago', '2009-03-07T10:30:00-06:00'], | |
300 // Same during daylight savings time. | |
301 ['2009-06-07 10:30', 'America/Chicago', '2009-06-07T10:30:00-05:00'], | |
302 // Create date object from date string. | |
303 ['2009-03-07', 'America/Chicago', '2009-03-07T00:00:00-06:00'], | |
304 // Same during daylight savings time. | |
305 ['2009-06-07', 'America/Chicago', '2009-06-07T00:00:00-05:00'], | |
306 // Create date object from date string. | |
307 ['2009-03-07 10:30', 'Australia/Canberra', '2009-03-07T10:30:00+11:00'], | |
308 // Same during daylight savings time. | |
309 ['2009-06-07 10:30', 'Australia/Canberra', '2009-06-07T10:30:00+10:00'], | |
310 ]; | |
311 | |
312 // On 32-bit systems, timestamps are limited to 1901-2038. | |
313 if (PHP_INT_SIZE > 4) { | |
314 // Create a date object in the distant past. | |
315 // @see https://www.drupal.org/node/2795489#comment-12127088 | |
316 if (version_compare(PHP_VERSION, '5.6.15', '>=')) { | |
317 $dates[] = ['1809-02-12 10:30', 'America/Chicago', '1809-02-12T10:30:00-06:00']; | |
318 } | |
319 // Create a date object in the far future. | |
320 $dates[] = ['2345-01-02 02:04', 'UTC', '2345-01-02T02:04:00+00:00']; | |
321 } | |
322 | |
323 return $dates; | |
324 } | |
325 | |
326 /** | |
327 * Provides data for date tests. | |
328 * | |
329 * @return array | |
330 * An array of arrays, each containing the input parameters for | |
331 * DateTimePlusTest::testDates(). | |
332 * | |
333 * @see DateTimePlusTest::testDates() | |
334 */ | |
335 public function providerTestDateArrays() { | |
336 $dates = [ | |
337 // Array input. | |
338 // Create date object from date array, date only. | |
339 [['year' => 2010, 'month' => 2, 'day' => 28], 'America/Chicago', '2010-02-28T00:00:00-06:00'], | |
340 // Create date object from date array with hour. | |
341 [['year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 10], 'America/Chicago', '2010-02-28T10:00:00-06:00'], | |
342 // Create date object from date array, date only. | |
343 [['year' => 2010, 'month' => 2, 'day' => 28], 'Europe/Berlin', '2010-02-28T00:00:00+01:00'], | |
344 // Create date object from date array with hour. | |
345 [['year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 10], 'Europe/Berlin', '2010-02-28T10:00:00+01:00'], | |
346 ]; | |
347 | |
348 // On 32-bit systems, timestamps are limited to 1901-2038. | |
349 if (PHP_INT_SIZE > 4) { | |
350 // Create a date object in the distant past. | |
351 // @see https://www.drupal.org/node/2795489#comment-12127088 | |
352 if (version_compare(PHP_VERSION, '5.6.15', '>=')) { | |
353 $dates[] = [['year' => 1809, 'month' => 2, 'day' => 12], 'America/Chicago', '1809-02-12T00:00:00-06:00']; | |
354 } | |
355 // Create a date object in the far future. | |
356 $dates[] = [['year' => 2345, 'month' => 1, 'day' => 2], 'UTC', '2345-01-02T00:00:00+00:00']; | |
357 } | |
358 | |
359 return $dates; | |
360 } | |
361 | |
362 /** | |
363 * Provides data for testDateFormats. | |
364 * | |
365 * @return array | |
366 * An array of arrays, each containing: | |
367 * - 'input' - Input to DateTimePlus. | |
368 * - 'timezone' - Timezone for DateTimePlus. | |
369 * - 'format' - Date format for DateTimePlus. | |
370 * - 'format_date' - Date format for use in $date->format() method. | |
371 * - 'expected' - The expected return from DateTimePlus. | |
372 * | |
373 * @see testDateFormats() | |
374 */ | |
375 public function providerTestDateFormat() { | |
376 return [ | |
377 // Create a year-only date. | |
378 ['2009', NULL, 'Y', 'Y', '2009'], | |
379 // Create a month and year-only date. | |
380 ['2009-10', NULL, 'Y-m', 'Y-m', '2009-10'], | |
381 // Create a time-only date. | |
382 ['T10:30:00', NULL, '\TH:i:s', 'H:i:s', '10:30:00'], | |
383 // Create a time-only date. | |
384 ['10:30:00', NULL, 'H:i:s', 'H:i:s', '10:30:00'], | |
385 ]; | |
386 } | |
387 | |
388 /** | |
389 * Provides data for testInvalidDates. | |
390 * | |
391 * @return array | |
392 * An array of arrays, each containing: | |
393 * - 'input' - Input for DateTimePlus. | |
394 * - 'timezone' - Timezone for DateTimePlus. | |
395 * - 'format' - Format for DateTimePlus. | |
396 * - 'message' - Message to display on failure. | |
397 * | |
398 * @see testInvalidDates | |
399 */ | |
400 public function providerTestInvalidDates() { | |
401 return [ | |
402 // Test for invalid month names when we are using a short version | |
403 // of the month. | |
404 ['23 abc 2012', NULL, 'd M Y', "23 abc 2012 contains an invalid month name and did not produce errors.", \InvalidArgumentException::class], | |
405 // Test for invalid hour. | |
406 ['0000-00-00T45:30:00', NULL, 'Y-m-d\TH:i:s', "0000-00-00T45:30:00 contains an invalid hour and did not produce errors.", \UnexpectedValueException::class], | |
407 // Test for invalid day. | |
408 ['0000-00-99T05:30:00', NULL, 'Y-m-d\TH:i:s', "0000-00-99T05:30:00 contains an invalid day and did not produce errors.", \UnexpectedValueException::class], | |
409 // Test for invalid month. | |
410 ['0000-75-00T15:30:00', NULL, 'Y-m-d\TH:i:s', "0000-75-00T15:30:00 contains an invalid month and did not produce errors.", \UnexpectedValueException::class], | |
411 // Test for invalid year. | |
412 ['11-08-01T15:30:00', NULL, 'Y-m-d\TH:i:s', "11-08-01T15:30:00 contains an invalid year and did not produce errors.", \UnexpectedValueException::class], | |
413 | |
414 ]; | |
415 } | |
416 | |
417 /** | |
418 * Data provider for testInvalidDateArrays. | |
419 * | |
420 * @return array | |
421 * An array of arrays, each containing: | |
422 * - 'input' - Input for DateTimePlus. | |
423 * - 'timezone' - Timezone for DateTimePlus. | |
424 * | |
425 * @see testInvalidDateArrays | |
426 */ | |
427 public function providerTestInvalidDateArrays() { | |
428 return [ | |
429 // One year larger than the documented upper limit of checkdate(). | |
430 [['year' => 32768, 'month' => 1, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], | |
431 // One year smaller than the documented lower limit of checkdate(). | |
432 [['year' => 0, 'month' => 1, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], | |
433 // Test for invalid month from date array. | |
434 [['year' => 2010, 'month' => 27, 'day' => 8, 'hour' => 8, 'minute' => 0, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], | |
435 // Test for invalid hour from date array. | |
436 [['year' => 2010, 'month' => 2, 'day' => 28, 'hour' => 80, 'minute' => 0, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], | |
437 // Test for invalid minute from date array. | |
438 [['year' => 2010, 'month' => 7, 'day' => 8, 'hour' => 8, 'minute' => 88, 'second' => 0], 'America/Chicago', \InvalidArgumentException::class], | |
439 // Regression test for https://www.drupal.org/node/2084455. | |
440 [['hour' => 59, 'minute' => 1, 'second' => 1], 'America/Chicago', \InvalidArgumentException::class], | |
441 ]; | |
442 } | |
443 | |
444 /** | |
445 * Provides data for testDateTimezone. | |
446 * | |
447 * @return array | |
448 * An array of arrays, each containing: | |
449 * - 'date' - Date string or object for DateTimePlus. | |
450 * - 'timezone' - Timezone string for DateTimePlus. | |
451 * - 'expected' - Expected return from DateTimePlus::getTimezone()::getName(). | |
452 * - 'message' - Message to display on test failure. | |
453 * | |
454 * @see testDateTimezone | |
455 */ | |
456 public function providerTestDateTimezone() { | |
457 // Use a common date for most of the tests. | |
458 $date_string = '2007-01-31 21:00:00'; | |
459 | |
460 // Detect the system timezone. | |
461 $system_timezone = date_default_timezone_get(); | |
462 | |
463 return [ | |
464 // Create a date object with an unspecified timezone, which should | |
465 // end up using the system timezone. | |
466 [$date_string, NULL, $system_timezone, 'DateTimePlus uses the system timezone when there is no site timezone.'], | |
467 // Create a date object with a specified timezone name. | |
468 [$date_string, 'America/Yellowknife', 'America/Yellowknife', 'DateTimePlus uses the specified timezone if provided.'], | |
469 // Create a date object with a timezone object. | |
470 [$date_string, new \DateTimeZone('Australia/Canberra'), 'Australia/Canberra', 'DateTimePlus uses the specified timezone if provided.'], | |
471 // Create a date object with another date object. | |
472 [new DateTimePlus('now', 'Pacific/Midway'), NULL, 'Pacific/Midway', 'DateTimePlus uses the specified timezone if provided.'], | |
473 ]; | |
474 } | |
475 | |
476 /** | |
477 * Provides data for testTimestamp. | |
478 * | |
479 * @return array | |
480 * An array of arrays, each containing the arguments required for | |
481 * self::testTimestamp(). | |
482 * | |
483 * @see testTimestamp() | |
484 */ | |
485 public function providerTestTimestamp() { | |
486 return [ | |
487 // Create date object from a unix timestamp and display it in | |
488 // local time. | |
489 [ | |
490 'input' => 0, | |
491 'initial' => [ | |
492 'timezone' => 'UTC', | |
493 'format' => 'c', | |
494 'expected_date' => '1970-01-01T00:00:00+00:00', | |
495 'expected_timezone' => 'UTC', | |
496 'expected_offset' => 0, | |
497 ], | |
498 'transform' => [ | |
499 'timezone' => 'America/Los_Angeles', | |
500 'format' => 'c', | |
501 'expected_date' => '1969-12-31T16:00:00-08:00', | |
502 'expected_timezone' => 'America/Los_Angeles', | |
503 'expected_offset' => '-28800', | |
504 ], | |
505 ], | |
506 // Create a date using the timestamp of zero, then display its | |
507 // value both in UTC and the local timezone. | |
508 [ | |
509 'input' => 0, | |
510 'initial' => [ | |
511 'timezone' => 'America/Los_Angeles', | |
512 'format' => 'c', | |
513 'expected_date' => '1969-12-31T16:00:00-08:00', | |
514 'expected_timezone' => 'America/Los_Angeles', | |
515 'expected_offset' => '-28800', | |
516 ], | |
517 'transform' => [ | |
518 'timezone' => 'UTC', | |
519 'format' => 'c', | |
520 'expected_date' => '1970-01-01T00:00:00+00:00', | |
521 'expected_timezone' => 'UTC', | |
522 'expected_offset' => 0, | |
523 ], | |
524 ], | |
525 ]; | |
526 } | |
527 | |
528 /** | |
529 * Provides data for testDateTimestamp. | |
530 * | |
531 * @return array | |
532 * An array of arrays, each containing the arguments required for | |
533 * self::testDateTimestamp(). | |
534 * | |
535 * @see testDateTimestamp() | |
536 */ | |
537 public function providerTestDateTimestamp() { | |
538 return [ | |
539 // Create date object from datetime string in UTC, and convert | |
540 // it to a local date. | |
541 [ | |
542 'input' => '1970-01-01 00:00:00', | |
543 'initial' => [ | |
544 'timezone' => 'UTC', | |
545 'format' => 'c', | |
546 'expected_date' => '1970-01-01T00:00:00+00:00', | |
547 'expected_timezone' => 'UTC', | |
548 'expected_offset' => 0, | |
549 ], | |
550 'transform' => [ | |
551 'timezone' => 'America/Los_Angeles', | |
552 'format' => 'c', | |
553 'expected_date' => '1969-12-31T16:00:00-08:00', | |
554 'expected_timezone' => 'America/Los_Angeles', | |
555 'expected_offset' => '-28800', | |
556 ], | |
557 ], | |
558 // Convert the local time to UTC using string input. | |
559 [ | |
560 'input' => '1969-12-31 16:00:00', | |
561 'initial' => [ | |
562 'timezone' => 'America/Los_Angeles', | |
563 'format' => 'c', | |
564 'expected_date' => '1969-12-31T16:00:00-08:00', | |
565 'expected_timezone' => 'America/Los_Angeles', | |
566 'expected_offset' => '-28800', | |
567 ], | |
568 'transform' => [ | |
569 'timezone' => 'UTC', | |
570 'format' => 'c', | |
571 'expected_date' => '1970-01-01T00:00:00+00:00', | |
572 'expected_timezone' => 'UTC', | |
573 'expected_offset' => 0, | |
574 ], | |
575 ], | |
576 // Convert the local time to UTC using string input. | |
577 [ | |
578 'input' => '1969-12-31 16:00:00', | |
579 'initial' => [ | |
580 'timezone' => 'Europe/Warsaw', | |
581 'format' => 'c', | |
582 'expected_date' => '1969-12-31T16:00:00+01:00', | |
583 'expected_timezone' => 'Europe/Warsaw', | |
584 'expected_offset' => '+3600', | |
585 ], | |
586 'transform' => [ | |
587 'timezone' => 'UTC', | |
588 'format' => 'c', | |
589 'expected_date' => '1969-12-31T15:00:00+00:00', | |
590 'expected_timezone' => 'UTC', | |
591 'expected_offset' => 0, | |
592 ], | |
593 ], | |
594 ]; | |
595 } | |
596 | |
597 /** | |
598 * Provides data for date tests. | |
599 * | |
600 * @return array | |
601 * An array of arrays, each containing the input parameters for | |
602 * DateTimePlusTest::testDateDiff(). | |
603 * | |
604 * @see DateTimePlusTest::testDateDiff() | |
605 */ | |
606 public function providerTestDateDiff() { | |
607 | |
608 $empty_interval = new \DateInterval('PT0S'); | |
609 | |
610 $positive_19_hours = new \DateInterval('PT19H'); | |
611 | |
612 $positive_18_hours = new \DateInterval('PT18H'); | |
613 | |
614 $positive_1_hour = new \DateInterval('PT1H'); | |
615 | |
616 $negative_1_hour = new \DateInterval('PT1H'); | |
617 $negative_1_hour->invert = 1; | |
618 | |
619 return [ | |
620 // There should be a 19 hour time interval between | |
621 // new years in Sydney and new years in LA in year 2000. | |
622 [ | |
623 'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')), | |
624 'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')), | |
625 'absolute' => FALSE, | |
626 'expected' => $positive_19_hours, | |
627 ], | |
628 // In 1970 Sydney did not observe daylight savings time | |
629 // So there is only a 18 hour time interval. | |
630 [ | |
631 'input2' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('Australia/Sydney')), | |
632 'input1' => DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles')), | |
633 'absolute' => FALSE, | |
634 'expected' => $positive_18_hours, | |
635 ], | |
636 [ | |
637 'input1' => DateTimePlus::createFromFormat('U', 3600, new \DateTimeZone('America/Los_Angeles')), | |
638 'input2' => DateTimePlus::createFromFormat('U', 0, new \DateTimeZone('UTC')), | |
639 'absolute' => FALSE, | |
640 'expected' => $negative_1_hour, | |
641 ], | |
642 [ | |
643 'input1' => DateTimePlus::createFromFormat('U', 3600), | |
644 'input2' => DateTimePlus::createFromFormat('U', 0), | |
645 'absolute' => FALSE, | |
646 'expected' => $negative_1_hour, | |
647 ], | |
648 [ | |
649 'input1' => DateTimePlus::createFromFormat('U', 3600), | |
650 'input2' => \DateTime::createFromFormat('U', 0), | |
651 'absolute' => FALSE, | |
652 'expected' => $negative_1_hour, | |
653 ], | |
654 [ | |
655 'input1' => DateTimePlus::createFromFormat('U', 3600), | |
656 'input2' => DateTimePlus::createFromFormat('U', 0), | |
657 'absolute' => TRUE, | |
658 'expected' => $positive_1_hour, | |
659 ], | |
660 [ | |
661 'input1' => DateTimePlus::createFromFormat('U', 3600), | |
662 'input2' => \DateTime::createFromFormat('U', 0), | |
663 'absolute' => TRUE, | |
664 'expected' => $positive_1_hour, | |
665 ], | |
666 [ | |
667 'input1' => DateTimePlus::createFromFormat('U', 0), | |
668 'input2' => DateTimePlus::createFromFormat('U', 0), | |
669 'absolute' => FALSE, | |
670 'expected' => $empty_interval, | |
671 ], | |
672 ]; | |
673 } | |
674 | |
675 /** | |
676 * Provides data for date tests. | |
677 * | |
678 * @return array | |
679 * An array of arrays, each containing the input parameters for | |
680 * DateTimePlusTest::testInvalidDateDiff(). | |
681 * | |
682 * @see DateTimePlusTest::testInvalidDateDiff() | |
683 */ | |
684 public function providerTestInvalidDateDiff() { | |
685 return [ | |
686 [ | |
687 'input1' => DateTimePlus::createFromFormat('U', 3600), | |
688 'input2' => '1970-01-01 00:00:00', | |
689 'absolute' => FALSE, | |
690 ], | |
691 [ | |
692 'input1' => DateTimePlus::createFromFormat('U', 3600), | |
693 'input2' => NULL, | |
694 'absolute' => FALSE, | |
695 ], | |
696 ]; | |
697 } | |
698 | |
699 /** | |
700 * Tests invalid values passed to constructor. | |
701 * | |
702 * @param string $time | |
703 * A date/time string. | |
704 * @param string[] $errors | |
705 * An array of error messages. | |
706 * | |
707 * @covers ::__construct | |
708 * | |
709 * @dataProvider providerTestInvalidConstructor | |
710 */ | |
711 public function testInvalidConstructor($time, array $errors) { | |
712 $date = new DateTimePlus($time); | |
713 | |
714 $this->assertEquals(TRUE, $date->hasErrors()); | |
715 $this->assertEquals($errors, $date->getErrors()); | |
716 } | |
717 | |
718 /** | |
719 * Provider for testInvalidConstructor(). | |
720 * | |
721 * @return array | |
722 * An array of invalid date/time strings, and corresponding error messages. | |
723 */ | |
724 public function providerTestInvalidConstructor() { | |
725 return [ | |
726 [ | |
727 'YYYY-MM-DD', | |
728 [ | |
729 'The timezone could not be found in the database', | |
730 'Unexpected character', | |
731 'Double timezone specification', | |
732 ], | |
733 ], | |
734 [ | |
735 '2017-MM-DD', | |
736 [ | |
737 'Unexpected character', | |
738 'The timezone could not be found in the database', | |
739 ], | |
740 ], | |
741 [ | |
742 'YYYY-03-DD', | |
743 [ | |
744 'The timezone could not be found in the database', | |
745 'Unexpected character', | |
746 'Double timezone specification', | |
747 ], | |
748 ], | |
749 [ | |
750 'YYYY-MM-07', | |
751 [ | |
752 'The timezone could not be found in the database', | |
753 'Unexpected character', | |
754 'Double timezone specification', | |
755 ], | |
756 ], | |
757 [ | |
758 '2017-13-55', | |
759 [ | |
760 'Unexpected character', | |
761 ], | |
762 ], | |
763 [ | |
764 'YYYY-MM-DD hh:mm:ss', | |
765 [ | |
766 'The timezone could not be found in the database', | |
767 'Unexpected character', | |
768 'Double timezone specification', | |
769 ], | |
770 ], | |
771 [ | |
772 '2017-03-07 25:70:80', | |
773 [ | |
774 'Unexpected character', | |
775 'Double time specification', | |
776 ], | |
777 ], | |
778 [ | |
779 'lorem ipsum dolor sit amet', | |
780 [ | |
781 'The timezone could not be found in the database', | |
782 'Double timezone specification', | |
783 ], | |
784 ], | |
785 ]; | |
786 } | |
787 | |
788 /** | |
789 * Tests the $settings['validate_format'] parameter in ::createFromFormat(). | |
790 */ | |
791 public function testValidateFormat() { | |
792 // Check that an input that does not strictly follow the input format will | |
793 // produce the desired date. In this case the year string '11' doesn't | |
794 // precisely match the 'Y' formater parameter, but PHP will parse it | |
795 // regardless. However, when formatted with the same string, the year will | |
796 // be output with four digits. With the ['validate_format' => FALSE] | |
797 // $settings, this will not thrown an exception. | |
798 $date = DateTimePlus::createFromFormat('Y-m-d H:i:s', '11-03-31 17:44:00', 'UTC', ['validate_format' => FALSE]); | |
799 $this->assertEquals('0011-03-31 17:44:00', $date->format('Y-m-d H:i:s')); | |
800 | |
801 // Parse the same date with ['validate_format' => TRUE] and make sure we | |
802 // get the expected exception. | |
803 $this->setExpectedException(\UnexpectedValueException::class); | |
804 $date = DateTimePlus::createFromFormat('Y-m-d H:i:s', '11-03-31 17:44:00', 'UTC', ['validate_format' => TRUE]); | |
805 } | |
806 | |
807 /** | |
808 * Tests that object methods are chainable. | |
809 * | |
810 * @covers ::__call | |
811 */ | |
812 public function testChainable() { | |
813 $date = new DateTimePlus('now', 'Australia/Sydney'); | |
814 | |
815 $date->setTimestamp(12345678); | |
816 $rendered = $date->render(); | |
817 $this->assertEquals('1970-05-24 07:21:18 Australia/Sydney', $rendered); | |
818 | |
819 $date->setTimestamp(23456789); | |
820 $rendered = $date->setTimezone(new \DateTimeZone('America/New_York'))->render(); | |
821 $this->assertEquals('1970-09-29 07:46:29 America/New_York', $rendered); | |
822 | |
823 $date = DateTimePlus::createFromFormat('Y-m-d H:i:s', '1970-05-24 07:21:18', new \DateTimeZone('Australia/Sydney')) | |
824 ->setTimezone(new \DateTimeZone('America/New_York')); | |
825 $rendered = $date->render(); | |
826 $this->assertInstanceOf(DateTimePlus::class, $date); | |
827 $this->assertEquals(12345678, $date->getTimestamp()); | |
828 $this->assertEquals('1970-05-23 17:21:18 America/New_York', $rendered); | |
829 } | |
830 | |
831 /** | |
832 * Tests that non-chainable methods work. | |
833 * | |
834 * @covers ::__call | |
835 */ | |
836 public function testChainableNonChainable() { | |
837 $datetime1 = new DateTimePlus('2009-10-11 12:00:00'); | |
838 $datetime2 = new DateTimePlus('2009-10-13 12:00:00'); | |
839 $interval = $datetime1->diff($datetime2); | |
840 $this->assertInstanceOf(\DateInterval::class, $interval); | |
841 $this->assertEquals('+2 days', $interval->format('%R%a days')); | |
842 } | |
843 | |
844 /** | |
845 * Tests that chained calls to non-existent functions throw an exception. | |
846 * | |
847 * @covers ::__call | |
848 */ | |
849 public function testChainableNonCallable() { | |
850 $this->setExpectedException(\BadMethodCallException::class, 'Call to undefined method Drupal\Component\Datetime\DateTimePlus::nonexistent()'); | |
851 $date = new DateTimePlus('now', 'Australia/Sydney'); | |
852 $date->setTimezone(new \DateTimeZone('America/New_York'))->nonexistent(); | |
853 } | |
854 | |
855 } |