Pull merge.
[yaffs-website] / web / core / tests / Drupal / Tests / Core / Datetime / DrupalDateTimeTest.php
1 <?php
2
3 namespace Drupal\Tests\Core\Datetime;
4
5 use Drupal\Core\Datetime\DrupalDateTime;
6 use Drupal\Tests\UnitTestCase;
7
8 /**
9  * @coversDefaultClass \Drupal\Core\Datetime\DrupalDateTime
10  * @group Datetime
11  */
12 class DrupalDateTimeTest extends UnitTestCase {
13
14   /**
15    * Test date diffs.
16    *
17    * @param mixed $input1
18    *   A DrupalDateTime object.
19    * @param mixed $input2
20    *   Date argument for DrupalDateTime::diff method.
21    * @param bool $absolute
22    *   Absolute flag for DrupalDateTime::diff method.
23    * @param \DateInterval $expected
24    *   The expected result of the DrupalDateTime::diff operation.
25    *
26    * @dataProvider providerTestDateDiff
27    */
28   public function testDateDiff($input1, $input2, $absolute, \DateInterval $expected) {
29     $interval = $input1->diff($input2, $absolute);
30     $this->assertEquals($interval, $expected);
31   }
32
33   /**
34    * Test date diff exception caused by invalid input.
35    *
36    * @param mixed $input1
37    *   A DateTimePlus object.
38    * @param mixed $input2
39    *   Date argument for DateTimePlus::diff method.
40    * @param bool $absolute
41    *   Absolute flag for DateTimePlus::diff method.
42    *
43    * @dataProvider providerTestInvalidDateDiff
44    */
45   public function testInvalidDateDiff($input1, $input2, $absolute) {
46     $this->setExpectedException(\BadMethodCallException::class, 'Method Drupal\Component\Datetime\DateTimePlus::diff expects parameter 1 to be a \DateTime or \Drupal\Component\Datetime\DateTimePlus object');
47     $interval = $input1->diff($input2, $absolute);
48   }
49
50   /**
51    * Provides data for date tests.
52    *
53    * @return array
54    *   An array of arrays, each containing the input parameters for
55    *   DrupalDateTimeTest::testDateDiff().
56    *
57    * @see DrupalDateTimeTest::testDateDiff()
58    */
59   public function providerTestDateDiff() {
60
61     $settings = ['langcode' => 'en'];
62
63     $utc_tz = new \DateTimeZone('UTC');
64
65     $empty_interval = new \DateInterval('PT0S');
66
67     $positive_19_hours = new \DateInterval('PT19H');
68
69     $positive_18_hours = new \DateInterval('PT18H');
70
71     $positive_1_hour = new \DateInterval('PT1H');
72
73     $negative_1_hour = new \DateInterval('PT1H');
74     $negative_1_hour->invert = 1;
75
76     return [
77
78       // There should be a 19 hour time interval between
79       // new years in Sydney and new years in LA in year 2000.
80       [
81         'input2' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('Australia/Sydney'), $settings),
82         'input1' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2000-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles'), $settings),
83         'absolute' => FALSE,
84         'expected' => $positive_19_hours,
85       ],
86       // In 1970 Sydney did not observe daylight savings time
87       // So there is only a 18 hour time interval.
88       [
89         'input2' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('Australia/Sydney'), $settings),
90         'input1' => DrupalDateTime::createFromFormat('Y-m-d H:i:s', '1970-01-01 00:00:00', new \DateTimeZone('America/Los_Angeles'), $settings),
91         'absolute' => FALSE,
92         'expected' => $positive_18_hours,
93       ],
94       [
95         'input1' => DrupalDateTime::createFromFormat('U', 3600, new \DateTimeZone('America/Los_Angeles'), $settings),
96         'input2' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
97         'absolute' => FALSE,
98         'expected' => $negative_1_hour,
99       ],
100       [
101         'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
102         'input2' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
103         'absolute' => FALSE,
104         'expected' => $negative_1_hour,
105       ],
106       [
107         'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
108         'input2' => \DateTime::createFromFormat('U', 0),
109         'absolute' => FALSE,
110         'expected' => $negative_1_hour,
111       ],
112       [
113         'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
114         'input2' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
115         'absolute' => TRUE,
116         'expected' => $positive_1_hour,
117       ],
118       [
119         'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
120         'input2' => \DateTime::createFromFormat('U', 0),
121         'absolute' => TRUE,
122         'expected' => $positive_1_hour,
123       ],
124       [
125         'input1' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
126         'input2' => DrupalDateTime::createFromFormat('U', 0, $utc_tz, $settings),
127         'absolute' => FALSE,
128         'expected' => $empty_interval,
129       ],
130     ];
131   }
132
133   /**
134    * Provides data for date tests.
135    *
136    * @return array
137    *   An array of arrays, each containing the input parameters for
138    *   DateTimePlusTest::testInvalidDateDiff().
139    *
140    * @see DateTimePlusTest::testInvalidDateDiff()
141    */
142   public function providerTestInvalidDateDiff() {
143     $settings = ['langcode' => 'en'];
144     $utc_tz = new \DateTimeZone('UTC');
145     return [
146       [
147         'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
148         'input2' => '1970-01-01 00:00:00',
149         'absolute' => FALSE,
150       ],
151       [
152         'input1' => DrupalDateTime::createFromFormat('U', 3600, $utc_tz, $settings),
153         'input2' => NULL,
154         'absolute' => FALSE,
155       ],
156     ];
157   }
158
159   /**
160    * Tests setting the default time for date-only objects.
161    */
162   public function testDefaultDateTime() {
163     $utc = new \DateTimeZone('UTC');
164
165     $date = DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2017-05-23 22:58:00', $utc, ['langcode' => 'en']);
166     $this->assertEquals('22:58:00', $date->format('H:i:s'));
167     $date->setDefaultDateTime();
168     $this->assertEquals('12:00:00', $date->format('H:i:s'));
169   }
170
171   /**
172    * Tests that object methods are chainable.
173    *
174    * @covers ::__call
175    */
176   public function testChainable() {
177     $tz = new \DateTimeZone(date_default_timezone_get());
178     $date = new DrupalDateTime('now', $tz, ['langcode' => 'en']);
179
180     $date->setTimestamp(12345678);
181     $rendered = $date->render();
182     $this->assertEquals('1970-05-24 07:21:18 Australia/Sydney', $rendered);
183
184     $date->setTimestamp(23456789);
185     $rendered = $date->setTimezone(new \DateTimeZone('America/New_York'))->render();
186     $this->assertEquals('1970-09-29 07:46:29 America/New_York', $rendered);
187   }
188
189   /**
190    * Tests that non-chainable methods work.
191    *
192    * @covers ::__call
193    */
194   public function testChainableNonChainable() {
195     $tz = new \DateTimeZone(date_default_timezone_get());
196     $datetime1 = new DrupalDateTime('2009-10-11 12:00:00', $tz, ['langcode' => 'en']);
197     $datetime2 = new DrupalDateTime('2009-10-13 12:00:00', $tz, ['langcode' => 'en']);
198     $interval = $datetime1->diff($datetime2);
199     $this->assertInstanceOf(\DateInterval::class, $interval);
200     $this->assertEquals('+2 days', $interval->format('%R%a days'));
201   }
202
203   /**
204    * Tests that chained calls to non-existent functions throw an exception.
205    *
206    * @covers ::__call
207    */
208   public function testChainableNonCallable() {
209     $this->setExpectedException(\BadMethodCallException::class, 'Call to undefined method Drupal\Core\Datetime\DrupalDateTime::nonexistent()');
210     $tz = new \DateTimeZone(date_default_timezone_get());
211     $date = new DrupalDateTime('now', $tz, ['langcode' => 'en']);
212     $date->setTimezone(new \DateTimeZone('America/New_York'))->nonexistent();
213   }
214
215   /**
216    * @covers ::getPhpDateTime
217    */
218   public function testGetPhpDateTime() {
219     $new_york = new \DateTimeZone('America/New_York');
220     $berlin = new \DateTimeZone('Europe/Berlin');
221
222     // Test retrieving a cloned copy of the wrapped \DateTime object, and that
223     // altering it does not change the DrupalDateTime object.
224     $drupaldatetime = DrupalDateTime::createFromFormat('Y-m-d H:i:s', '2017-07-13 22:40:00', $new_york, ['langcode' => 'en']);
225     $this->assertEquals(1500000000, $drupaldatetime->getTimestamp());
226     $this->assertEquals('America/New_York', $drupaldatetime->getTimezone()->getName());
227
228     $datetime = $drupaldatetime->getPhpDateTime();
229     $this->assertInstanceOf('DateTime', $datetime);
230     $this->assertEquals(1500000000, $datetime->getTimestamp());
231     $this->assertEquals('America/New_York', $datetime->getTimezone()->getName());
232
233     $datetime->setTimestamp(1400000000)->setTimezone($berlin);
234     $this->assertEquals(1400000000, $datetime->getTimestamp());
235     $this->assertEquals('Europe/Berlin', $datetime->getTimezone()->getName());
236     $this->assertEquals(1500000000, $drupaldatetime->getTimestamp());
237     $this->assertEquals('America/New_York', $drupaldatetime->getTimezone()->getName());
238   }
239
240 }