DateCasterTest.php 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\VarDumper\Tests\Caster;
  11. use PHPUnit\Framework\TestCase;
  12. use Symfony\Component\VarDumper\Caster\Caster;
  13. use Symfony\Component\VarDumper\Caster\DateCaster;
  14. use Symfony\Component\VarDumper\Cloner\Stub;
  15. use Symfony\Component\VarDumper\Test\VarDumperTestTrait;
  16. /**
  17. * @author Dany Maillard <danymaillard93b@gmail.com>
  18. */
  19. class DateCasterTest extends TestCase
  20. {
  21. use VarDumperTestTrait;
  22. /**
  23. * @dataProvider provideDateTimes
  24. */
  25. public function testDumpDateTime($time, $timezone, $xDate, $xTimestamp)
  26. {
  27. $date = new \DateTime($time, new \DateTimeZone($timezone));
  28. $xDump = <<<EODUMP
  29. DateTime @$xTimestamp {
  30. date: $xDate
  31. }
  32. EODUMP;
  33. $this->assertDumpEquals($xDump, $date);
  34. }
  35. /**
  36. * @dataProvider provideDateTimes
  37. */
  38. public function testCastDateTime($time, $timezone, $xDate, $xTimestamp, $xInfos)
  39. {
  40. $stub = new Stub();
  41. $date = new \DateTime($time, new \DateTimeZone($timezone));
  42. $cast = DateCaster::castDateTime($date, ['foo' => 'bar'], $stub, false, 0);
  43. $xDump = <<<EODUMP
  44. array:1 [
  45. "\\x00~\\x00date" => $xDate
  46. ]
  47. EODUMP;
  48. $this->assertDumpEquals($xDump, $cast);
  49. $xDump = <<<EODUMP
  50. Symfony\Component\VarDumper\Caster\ConstStub {
  51. +type: 1
  52. +class: "$xDate"
  53. +value: "%A$xInfos%A"
  54. +cut: 0
  55. +handle: 0
  56. +refCount: 0
  57. +position: 0
  58. +attr: []
  59. }
  60. EODUMP;
  61. $this->assertDumpMatchesFormat($xDump, $cast["\0~\0date"]);
  62. }
  63. public function provideDateTimes()
  64. {
  65. return [
  66. ['2017-04-30 00:00:00.000000', 'Europe/Zurich', '2017-04-30 00:00:00.0 Europe/Zurich (+02:00)', 1493503200, 'Sunday, April 30, 2017%Afrom now%ADST On'],
  67. ['2017-12-31 00:00:00.000000', 'Europe/Zurich', '2017-12-31 00:00:00.0 Europe/Zurich (+01:00)', 1514674800, 'Sunday, December 31, 2017%Afrom now%ADST Off'],
  68. ['2017-04-30 00:00:00.000000', '+02:00', '2017-04-30 00:00:00.0 +02:00', 1493503200, 'Sunday, April 30, 2017%Afrom now'],
  69. ['2017-04-30 00:00:00.100000', '+00:00', '2017-04-30 00:00:00.100 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'],
  70. ['2017-04-30 00:00:00.120000', '+00:00', '2017-04-30 00:00:00.120 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'],
  71. ['2017-04-30 00:00:00.123000', '+00:00', '2017-04-30 00:00:00.123 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'],
  72. ['2017-04-30 00:00:00.123400', '+00:00', '2017-04-30 00:00:00.123400 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'],
  73. ['2017-04-30 00:00:00.123450', '+00:00', '2017-04-30 00:00:00.123450 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'],
  74. ['2017-04-30 00:00:00.123456', '+00:00', '2017-04-30 00:00:00.123456 +00:00', 1493510400, 'Sunday, April 30, 2017%Afrom now'],
  75. ];
  76. }
  77. /**
  78. * @dataProvider provideIntervals
  79. */
  80. public function testDumpInterval($intervalSpec, $ms, $invert, $expected)
  81. {
  82. if ($ms && \PHP_VERSION_ID >= 70200 && version_compare(PHP_VERSION, '7.2.0rc3', '<=')) {
  83. $this->markTestSkipped('Skipped on 7.2 before rc4 because of php bug #75354.');
  84. }
  85. $interval = $this->createInterval($intervalSpec, $ms, $invert);
  86. $xDump = <<<EODUMP
  87. DateInterval {
  88. interval: $expected
  89. %A}
  90. EODUMP;
  91. $this->assertDumpMatchesFormat($xDump, $interval);
  92. }
  93. /**
  94. * @dataProvider provideIntervals
  95. */
  96. public function testDumpIntervalExcludingVerbosity($intervalSpec, $ms, $invert, $expected)
  97. {
  98. if ($ms && \PHP_VERSION_ID >= 70200 && version_compare(PHP_VERSION, '7.2.0rc3', '<=')) {
  99. $this->markTestSkipped('Skipped on 7.2 before rc4 because of php bug #75354.');
  100. }
  101. $interval = $this->createInterval($intervalSpec, $ms, $invert);
  102. $xDump = <<<EODUMP
  103. DateInterval {
  104. interval: $expected
  105. }
  106. EODUMP;
  107. $this->assertDumpEquals($xDump, $interval, Caster::EXCLUDE_VERBOSE);
  108. }
  109. /**
  110. * @dataProvider provideIntervals
  111. */
  112. public function testCastInterval($intervalSpec, $ms, $invert, $xInterval, $xSeconds)
  113. {
  114. if ($ms && \PHP_VERSION_ID >= 70200 && version_compare(PHP_VERSION, '7.2.0rc3', '<=')) {
  115. $this->markTestSkipped('Skipped on 7.2 before rc4 because of php bug #75354.');
  116. }
  117. $interval = $this->createInterval($intervalSpec, $ms, $invert);
  118. $stub = new Stub();
  119. $cast = DateCaster::castInterval($interval, ['foo' => 'bar'], $stub, false, Caster::EXCLUDE_VERBOSE);
  120. $xDump = <<<EODUMP
  121. array:1 [
  122. "\\x00~\\x00interval" => $xInterval
  123. ]
  124. EODUMP;
  125. $this->assertDumpEquals($xDump, $cast);
  126. if (null === $xSeconds) {
  127. return;
  128. }
  129. $xDump = <<<EODUMP
  130. Symfony\Component\VarDumper\Caster\ConstStub {
  131. +type: 1
  132. +class: "$xInterval"
  133. +value: "$xSeconds"
  134. +cut: 0
  135. +handle: 0
  136. +refCount: 0
  137. +position: 0
  138. +attr: []
  139. }
  140. EODUMP;
  141. $this->assertDumpMatchesFormat($xDump, $cast["\0~\0interval"]);
  142. }
  143. public function provideIntervals()
  144. {
  145. return [
  146. ['PT0S', 0, 0, '0s', '0s'],
  147. ['PT0S', 0.1, 0, '+ 00:00:00.100', '%is'],
  148. ['PT1S', 0, 0, '+ 00:00:01.0', '%is'],
  149. ['PT2M', 0, 0, '+ 00:02:00.0', '%is'],
  150. ['PT3H', 0, 0, '+ 03:00:00.0', '%ss'],
  151. ['P4D', 0, 0, '+ 4d', '%ss'],
  152. ['P5M', 0, 0, '+ 5m', null],
  153. ['P6Y', 0, 0, '+ 6y', null],
  154. ['P1Y2M3DT4H5M6S', 0, 0, '+ 1y 2m 3d 04:05:06.0', null],
  155. ['PT1M60S', 0, 0, '+ 00:02:00.0', null],
  156. ['PT1H60M', 0, 0, '+ 02:00:00.0', null],
  157. ['P1DT24H', 0, 0, '+ 2d', null],
  158. ['P1M32D', 0, 0, '+ 1m 32d', null],
  159. ['PT0S', 0, 1, '0s', '0s'],
  160. ['PT0S', 0.1, 1, '- 00:00:00.100', '%is'],
  161. ['PT1S', 0, 1, '- 00:00:01.0', '%is'],
  162. ['PT2M', 0, 1, '- 00:02:00.0', '%is'],
  163. ['PT3H', 0, 1, '- 03:00:00.0', '%ss'],
  164. ['P4D', 0, 1, '- 4d', '%ss'],
  165. ['P5M', 0, 1, '- 5m', null],
  166. ['P6Y', 0, 1, '- 6y', null],
  167. ['P1Y2M3DT4H5M6S', 0, 1, '- 1y 2m 3d 04:05:06.0', null],
  168. ['PT1M60S', 0, 1, '- 00:02:00.0', null],
  169. ['PT1H60M', 0, 1, '- 02:00:00.0', null],
  170. ['P1DT24H', 0, 1, '- 2d', null],
  171. ['P1M32D', 0, 1, '- 1m 32d', null],
  172. ];
  173. }
  174. /**
  175. * @dataProvider provideTimeZones
  176. */
  177. public function testDumpTimeZone($timezone, $expected)
  178. {
  179. $timezone = new \DateTimeZone($timezone);
  180. $xDump = <<<EODUMP
  181. DateTimeZone {
  182. timezone: $expected
  183. %A}
  184. EODUMP;
  185. $this->assertDumpMatchesFormat($xDump, $timezone);
  186. }
  187. /**
  188. * @dataProvider provideTimeZones
  189. */
  190. public function testDumpTimeZoneExcludingVerbosity($timezone, $expected)
  191. {
  192. $timezone = new \DateTimeZone($timezone);
  193. $xDump = <<<EODUMP
  194. DateTimeZone {
  195. timezone: $expected
  196. }
  197. EODUMP;
  198. $this->assertDumpMatchesFormat($xDump, $timezone, Caster::EXCLUDE_VERBOSE);
  199. }
  200. /**
  201. * @dataProvider provideTimeZones
  202. */
  203. public function testCastTimeZone($timezone, $xTimezone, $xRegion)
  204. {
  205. $timezone = new \DateTimeZone($timezone);
  206. $stub = new Stub();
  207. $cast = DateCaster::castTimeZone($timezone, ['foo' => 'bar'], $stub, false, Caster::EXCLUDE_VERBOSE);
  208. $xDump = <<<EODUMP
  209. array:1 [
  210. "\\x00~\\x00timezone" => $xTimezone
  211. ]
  212. EODUMP;
  213. $this->assertDumpMatchesFormat($xDump, $cast);
  214. $xDump = <<<EODUMP
  215. Symfony\Component\VarDumper\Caster\ConstStub {
  216. +type: 1
  217. +class: "$xTimezone"
  218. +value: "$xRegion"
  219. +cut: 0
  220. +handle: 0
  221. +refCount: 0
  222. +position: 0
  223. +attr: []
  224. }
  225. EODUMP;
  226. $this->assertDumpMatchesFormat($xDump, $cast["\0~\0timezone"]);
  227. }
  228. public function provideTimeZones()
  229. {
  230. $xRegion = \extension_loaded('intl') ? '%s' : '';
  231. return [
  232. // type 1 (UTC offset)
  233. ['-12:00', '-12:00', ''],
  234. ['+00:00', '+00:00', ''],
  235. ['+14:00', '+14:00', ''],
  236. // type 2 (timezone abbreviation)
  237. ['GMT', '+00:00', ''],
  238. ['a', '+01:00', ''],
  239. ['b', '+02:00', ''],
  240. ['z', '+00:00', ''],
  241. // type 3 (timezone identifier)
  242. ['Africa/Tunis', 'Africa/Tunis (%s:00)', $xRegion],
  243. ['America/Panama', 'America/Panama (%s:00)', $xRegion],
  244. ['Asia/Jerusalem', 'Asia/Jerusalem (%s:00)', $xRegion],
  245. ['Atlantic/Canary', 'Atlantic/Canary (%s:00)', $xRegion],
  246. ['Australia/Perth', 'Australia/Perth (%s:00)', $xRegion],
  247. ['Europe/Zurich', 'Europe/Zurich (%s:00)', $xRegion],
  248. ['Pacific/Tahiti', 'Pacific/Tahiti (%s:00)', $xRegion],
  249. ];
  250. }
  251. /**
  252. * @dataProvider providePeriods
  253. */
  254. public function testDumpPeriod($start, $interval, $end, $options, $expected)
  255. {
  256. $p = new \DatePeriod(new \DateTime($start), new \DateInterval($interval), \is_int($end) ? $end : new \DateTime($end), $options);
  257. $xDump = <<<EODUMP
  258. DatePeriod {
  259. period: $expected
  260. %A}
  261. EODUMP;
  262. $this->assertDumpMatchesFormat($xDump, $p);
  263. }
  264. /**
  265. * @dataProvider providePeriods
  266. */
  267. public function testCastPeriod($start, $interval, $end, $options, $xPeriod, $xDates)
  268. {
  269. $p = new \DatePeriod(new \DateTime($start), new \DateInterval($interval), \is_int($end) ? $end : new \DateTime($end), $options);
  270. $stub = new Stub();
  271. $cast = DateCaster::castPeriod($p, [], $stub, false, 0);
  272. $xDump = <<<EODUMP
  273. array:1 [
  274. "\\x00~\\x00period" => $xPeriod
  275. ]
  276. EODUMP;
  277. $this->assertDumpEquals($xDump, $cast);
  278. $xDump = <<<EODUMP
  279. Symfony\Component\VarDumper\Caster\ConstStub {
  280. +type: 1
  281. +class: "$xPeriod"
  282. +value: "%A$xDates%A"
  283. +cut: 0
  284. +handle: 0
  285. +refCount: 0
  286. +position: 0
  287. +attr: []
  288. }
  289. EODUMP;
  290. $this->assertDumpMatchesFormat($xDump, $cast["\0~\0period"]);
  291. }
  292. public function providePeriods()
  293. {
  294. $periods = [
  295. ['2017-01-01', 'P1D', '2017-01-03', 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) to 2017-01-03 00:00:00.0', '1) 2017-01-01%a2) 2017-01-02'],
  296. ['2017-01-01', 'P1D', 1, 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) recurring 2 time/s', '1) 2017-01-01%a2) 2017-01-02'],
  297. ['2017-01-01', 'P1D', '2017-01-04', 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) to 2017-01-04 00:00:00.0', '1) 2017-01-01%a2) 2017-01-02%a3) 2017-01-03'],
  298. ['2017-01-01', 'P1D', 2, 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) recurring 3 time/s', '1) 2017-01-01%a2) 2017-01-02%a3) 2017-01-03'],
  299. ['2017-01-01', 'P1D', '2017-01-05', 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) to 2017-01-05 00:00:00.0', '1) 2017-01-01%a2) 2017-01-02%a1 more'],
  300. ['2017-01-01', 'P1D', 3, 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) recurring 4 time/s', '1) 2017-01-01%a2) 2017-01-02%a3) 2017-01-03%a1 more'],
  301. ['2017-01-01', 'P1D', '2017-01-21', 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) to 2017-01-21 00:00:00.0', '1) 2017-01-01%a17 more'],
  302. ['2017-01-01', 'P1D', 19, 0, 'every + 1d, from 2017-01-01 00:00:00.0 (included) recurring 20 time/s', '1) 2017-01-01%a17 more'],
  303. ['2017-01-01 01:00:00', 'P1D', '2017-01-03 01:00:00', 0, 'every + 1d, from 2017-01-01 01:00:00.0 (included) to 2017-01-03 01:00:00.0', '1) 2017-01-01 01:00:00.0%a2) 2017-01-02 01:00:00.0'],
  304. ['2017-01-01 01:00:00', 'P1D', 1, 0, 'every + 1d, from 2017-01-01 01:00:00.0 (included) recurring 2 time/s', '1) 2017-01-01 01:00:00.0%a2) 2017-01-02 01:00:00.0'],
  305. ['2017-01-01', 'P1DT1H', '2017-01-03', 0, 'every + 1d 01:00:00.0, from 2017-01-01 00:00:00.0 (included) to 2017-01-03 00:00:00.0', '1) 2017-01-01 00:00:00.0%a2) 2017-01-02 01:00:00.0'],
  306. ['2017-01-01', 'P1DT1H', 1, 0, 'every + 1d 01:00:00.0, from 2017-01-01 00:00:00.0 (included) recurring 2 time/s', '1) 2017-01-01 00:00:00.0%a2) 2017-01-02 01:00:00.0'],
  307. ['2017-01-01', 'P1D', '2017-01-04', \DatePeriod::EXCLUDE_START_DATE, 'every + 1d, from 2017-01-01 00:00:00.0 (excluded) to 2017-01-04 00:00:00.0', '1) 2017-01-02%a2) 2017-01-03'],
  308. ['2017-01-01', 'P1D', 2, \DatePeriod::EXCLUDE_START_DATE, 'every + 1d, from 2017-01-01 00:00:00.0 (excluded) recurring 2 time/s', '1) 2017-01-02%a2) 2017-01-03'],
  309. ];
  310. if (\PHP_VERSION_ID < 70107) {
  311. array_walk($periods, function (&$i) { $i[5] = ''; });
  312. }
  313. return $periods;
  314. }
  315. private function createInterval($intervalSpec, $ms, $invert)
  316. {
  317. $interval = new \DateInterval($intervalSpec);
  318. $interval->f = $ms;
  319. $interval->invert = $invert;
  320. return $interval;
  321. }
  322. }