Chris@12: Chris@12: * Chris@12: * For the full copyright and license information, please view the LICENSE Chris@12: * file that was distributed with this source code. Chris@12: */ Chris@12: Chris@12: namespace Symfony\Component\VarDumper\Tests\Caster; Chris@12: Chris@12: use PHPUnit\Framework\TestCase; Chris@12: use Symfony\Component\VarDumper\Caster\Caster; Chris@12: use Symfony\Component\VarDumper\Caster\DateCaster; Chris@12: use Symfony\Component\VarDumper\Cloner\Stub; Chris@12: use Symfony\Component\VarDumper\Test\VarDumperTestTrait; Chris@12: Chris@12: /** Chris@12: * @author Dany Maillard Chris@12: */ Chris@12: class DateCasterTest extends TestCase Chris@12: { Chris@12: use VarDumperTestTrait; Chris@12: Chris@12: /** Chris@12: * @dataProvider provideDateTimes Chris@12: */ Chris@12: public function testDumpDateTime($time, $timezone, $xDate, $xTimestamp) Chris@12: { Chris@17: if ((\defined('HHVM_VERSION_ID') || \PHP_VERSION_ID <= 50509) && preg_match('/[-+]\d{2}:\d{2}/', $timezone)) { Chris@12: $this->markTestSkipped('DateTimeZone GMT offsets are supported since 5.5.10. See https://github.com/facebook/hhvm/issues/5875 for HHVM.'); Chris@12: } Chris@12: Chris@12: $date = new \DateTime($time, new \DateTimeZone($timezone)); Chris@12: Chris@12: $xDump = <<assertDumpEquals($xDump, $date); Chris@12: } Chris@12: Chris@12: /** Chris@12: * @dataProvider provideDateTimes Chris@12: */ Chris@12: public function testCastDateTime($time, $timezone, $xDate, $xTimestamp, $xInfos) Chris@12: { Chris@17: if ((\defined('HHVM_VERSION_ID') || \PHP_VERSION_ID <= 50509) && preg_match('/[-+]\d{2}:\d{2}/', $timezone)) { Chris@12: $this->markTestSkipped('DateTimeZone GMT offsets are supported since 5.5.10. See https://github.com/facebook/hhvm/issues/5875 for HHVM.'); Chris@12: } Chris@12: Chris@12: $stub = new Stub(); Chris@12: $date = new \DateTime($time, new \DateTimeZone($timezone)); Chris@17: $cast = DateCaster::castDateTime($date, ['foo' => 'bar'], $stub, false, 0); Chris@12: Chris@12: $xDump = << $xDate Chris@12: ] Chris@12: EODUMP; Chris@12: Chris@12: $this->assertDumpEquals($xDump, $cast); Chris@12: Chris@12: $xDump = <<assertDumpMatchesFormat($xDump, $cast["\0~\0date"]); Chris@12: } Chris@12: Chris@12: public function provideDateTimes() Chris@12: { Chris@17: return [ Chris@17: ['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'], Chris@17: ['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'], Chris@17: ['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'], Chris@12: Chris@17: ['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'], Chris@17: ['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'], Chris@17: ['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'], Chris@17: ['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'], Chris@17: ['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'], Chris@17: ['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'], Chris@17: ]; Chris@12: } Chris@12: Chris@12: /** Chris@12: * @dataProvider provideIntervals Chris@12: */ Chris@12: public function testDumpInterval($intervalSpec, $ms, $invert, $expected) Chris@12: { Chris@17: if ($ms && \PHP_VERSION_ID >= 70200 && version_compare(PHP_VERSION, '7.2.0rc3', '<=')) { Chris@12: $this->markTestSkipped('Skipped on 7.2 before rc4 because of php bug #75354.'); Chris@12: } Chris@12: Chris@12: $interval = $this->createInterval($intervalSpec, $ms, $invert); Chris@12: Chris@12: $xDump = <<assertDumpMatchesFormat($xDump, $interval); Chris@12: } Chris@12: Chris@12: /** Chris@12: * @dataProvider provideIntervals Chris@12: */ Chris@12: public function testDumpIntervalExcludingVerbosity($intervalSpec, $ms, $invert, $expected) Chris@12: { Chris@17: if ($ms && \PHP_VERSION_ID >= 70200 && version_compare(PHP_VERSION, '7.2.0rc3', '<=')) { Chris@12: $this->markTestSkipped('Skipped on 7.2 before rc4 because of php bug #75354.'); Chris@12: } Chris@12: Chris@12: $interval = $this->createInterval($intervalSpec, $ms, $invert); Chris@12: Chris@12: $xDump = <<assertDumpEquals($xDump, $interval, Caster::EXCLUDE_VERBOSE); Chris@12: } Chris@12: Chris@12: /** Chris@12: * @dataProvider provideIntervals Chris@12: */ Chris@12: public function testCastInterval($intervalSpec, $ms, $invert, $xInterval, $xSeconds) Chris@12: { Chris@17: if ($ms && \PHP_VERSION_ID >= 70200 && version_compare(PHP_VERSION, '7.2.0rc3', '<=')) { Chris@12: $this->markTestSkipped('Skipped on 7.2 before rc4 because of php bug #75354.'); Chris@12: } Chris@12: Chris@12: $interval = $this->createInterval($intervalSpec, $ms, $invert); Chris@12: $stub = new Stub(); Chris@12: Chris@17: $cast = DateCaster::castInterval($interval, ['foo' => 'bar'], $stub, false, Caster::EXCLUDE_VERBOSE); Chris@12: Chris@12: $xDump = << $xInterval Chris@12: ] Chris@12: EODUMP; Chris@12: Chris@12: $this->assertDumpEquals($xDump, $cast); Chris@12: Chris@12: if (null === $xSeconds) { Chris@12: return; Chris@12: } Chris@12: Chris@12: $xDump = <<assertDumpMatchesFormat($xDump, $cast["\0~\0interval"]); Chris@12: } Chris@12: Chris@12: public function provideIntervals() Chris@12: { Chris@12: $i = new \DateInterval('PT0S'); Chris@12: $ms = ($withMs = \PHP_VERSION_ID >= 70100 && isset($i->f)) ? '.0' : ''; Chris@12: Chris@17: return [ Chris@17: ['PT0S', 0, 0, '0s', '0s'], Chris@17: ['PT0S', 0.1, 0, $withMs ? '+ 00:00:00.100' : '0s', '%is'], Chris@17: ['PT1S', 0, 0, '+ 00:00:01'.$ms, '%is'], Chris@17: ['PT2M', 0, 0, '+ 00:02:00'.$ms, '%is'], Chris@17: ['PT3H', 0, 0, '+ 03:00:00'.$ms, '%ss'], Chris@17: ['P4D', 0, 0, '+ 4d', '%ss'], Chris@17: ['P5M', 0, 0, '+ 5m', null], Chris@17: ['P6Y', 0, 0, '+ 6y', null], Chris@17: ['P1Y2M3DT4H5M6S', 0, 0, '+ 1y 2m 3d 04:05:06'.$ms, null], Chris@17: ['PT1M60S', 0, 0, '+ 00:02:00'.$ms, null], Chris@17: ['PT1H60M', 0, 0, '+ 02:00:00'.$ms, null], Chris@17: ['P1DT24H', 0, 0, '+ 2d', null], Chris@17: ['P1M32D', 0, 0, '+ 1m 32d', null], Chris@12: Chris@17: ['PT0S', 0, 1, '0s', '0s'], Chris@17: ['PT0S', 0.1, 1, $withMs ? '- 00:00:00.100' : '0s', '%is'], Chris@17: ['PT1S', 0, 1, '- 00:00:01'.$ms, '%is'], Chris@17: ['PT2M', 0, 1, '- 00:02:00'.$ms, '%is'], Chris@17: ['PT3H', 0, 1, '- 03:00:00'.$ms, '%ss'], Chris@17: ['P4D', 0, 1, '- 4d', '%ss'], Chris@17: ['P5M', 0, 1, '- 5m', null], Chris@17: ['P6Y', 0, 1, '- 6y', null], Chris@17: ['P1Y2M3DT4H5M6S', 0, 1, '- 1y 2m 3d 04:05:06'.$ms, null], Chris@17: ['PT1M60S', 0, 1, '- 00:02:00'.$ms, null], Chris@17: ['PT1H60M', 0, 1, '- 02:00:00'.$ms, null], Chris@17: ['P1DT24H', 0, 1, '- 2d', null], Chris@17: ['P1M32D', 0, 1, '- 1m 32d', null], Chris@17: ]; Chris@12: } Chris@12: Chris@12: /** Chris@12: * @dataProvider provideTimeZones Chris@12: */ Chris@12: public function testDumpTimeZone($timezone, $expected) Chris@12: { Chris@17: if ((\defined('HHVM_VERSION_ID') || \PHP_VERSION_ID <= 50509) && !preg_match('/\w+\/\w+/', $timezone)) { Chris@12: $this->markTestSkipped('DateTimeZone GMT offsets are supported since 5.5.10. See https://github.com/facebook/hhvm/issues/5875 for HHVM.'); Chris@12: } Chris@12: Chris@12: $timezone = new \DateTimeZone($timezone); Chris@12: Chris@12: $xDump = <<assertDumpMatchesFormat($xDump, $timezone); Chris@12: } Chris@12: Chris@12: /** Chris@12: * @dataProvider provideTimeZones Chris@12: */ Chris@12: public function testDumpTimeZoneExcludingVerbosity($timezone, $expected) Chris@12: { Chris@17: if ((\defined('HHVM_VERSION_ID') || \PHP_VERSION_ID <= 50509) && !preg_match('/\w+\/\w+/', $timezone)) { Chris@12: $this->markTestSkipped('DateTimeZone GMT offsets are supported since 5.5.10. See https://github.com/facebook/hhvm/issues/5875 for HHVM.'); Chris@12: } Chris@12: Chris@12: $timezone = new \DateTimeZone($timezone); Chris@12: Chris@12: $xDump = <<assertDumpMatchesFormat($xDump, $timezone, Caster::EXCLUDE_VERBOSE); Chris@12: } Chris@12: Chris@12: /** Chris@12: * @dataProvider provideTimeZones Chris@12: */ Chris@12: public function testCastTimeZone($timezone, $xTimezone, $xRegion) Chris@12: { Chris@17: if ((\defined('HHVM_VERSION_ID') || \PHP_VERSION_ID <= 50509) && !preg_match('/\w+\/\w+/', $timezone)) { Chris@12: $this->markTestSkipped('DateTimeZone GMT offsets are supported since 5.5.10. See https://github.com/facebook/hhvm/issues/5875 for HHVM.'); Chris@12: } Chris@12: Chris@12: $timezone = new \DateTimeZone($timezone); Chris@12: $stub = new Stub(); Chris@12: Chris@17: $cast = DateCaster::castTimeZone($timezone, ['foo' => 'bar'], $stub, false, Caster::EXCLUDE_VERBOSE); Chris@12: Chris@12: $xDump = << $xTimezone Chris@12: ] Chris@12: EODUMP; Chris@12: Chris@12: $this->assertDumpMatchesFormat($xDump, $cast); Chris@12: Chris@12: $xDump = <<assertDumpMatchesFormat($xDump, $cast["\0~\0timezone"]); Chris@12: } Chris@12: Chris@12: public function provideTimeZones() Chris@12: { Chris@17: $xRegion = \extension_loaded('intl') ? '%s' : ''; Chris@12: Chris@17: return [ Chris@12: // type 1 (UTC offset) Chris@17: ['-12:00', '-12:00', ''], Chris@17: ['+00:00', '+00:00', ''], Chris@17: ['+14:00', '+14:00', ''], Chris@12: Chris@12: // type 2 (timezone abbreviation) Chris@17: ['GMT', '+00:00', ''], Chris@17: ['a', '+01:00', ''], Chris@17: ['b', '+02:00', ''], Chris@17: ['z', '+00:00', ''], Chris@12: Chris@12: // type 3 (timezone identifier) Chris@17: ['Africa/Tunis', 'Africa/Tunis (%s:00)', $xRegion], Chris@17: ['America/Panama', 'America/Panama (%s:00)', $xRegion], Chris@17: ['Asia/Jerusalem', 'Asia/Jerusalem (%s:00)', $xRegion], Chris@17: ['Atlantic/Canary', 'Atlantic/Canary (%s:00)', $xRegion], Chris@17: ['Australia/Perth', 'Australia/Perth (%s:00)', $xRegion], Chris@17: ['Europe/Zurich', 'Europe/Zurich (%s:00)', $xRegion], Chris@17: ['Pacific/Tahiti', 'Pacific/Tahiti (%s:00)', $xRegion], Chris@17: ]; Chris@12: } Chris@12: Chris@12: /** Chris@12: * @dataProvider providePeriods Chris@12: */ Chris@12: public function testDumpPeriod($start, $interval, $end, $options, $expected) Chris@12: { Chris@17: if (\defined('HHVM_VERSION_ID') || \PHP_VERSION_ID < 50620 || (\PHP_VERSION_ID >= 70000 && \PHP_VERSION_ID < 70005)) { Chris@12: $this->markTestSkipped(); Chris@12: } Chris@12: Chris@17: $p = new \DatePeriod(new \DateTime($start), new \DateInterval($interval), \is_int($end) ? $end : new \DateTime($end), $options); Chris@12: Chris@12: $xDump = <<assertDumpMatchesFormat($xDump, $p); Chris@12: } Chris@12: Chris@12: /** Chris@12: * @dataProvider providePeriods Chris@12: */ Chris@12: public function testCastPeriod($start, $interval, $end, $options, $xPeriod, $xDates) Chris@12: { Chris@17: if (\defined('HHVM_VERSION_ID') || \PHP_VERSION_ID < 50620 || (\PHP_VERSION_ID >= 70000 && \PHP_VERSION_ID < 70005)) { Chris@12: $this->markTestSkipped(); Chris@12: } Chris@12: Chris@17: $p = new \DatePeriod(new \DateTime($start), new \DateInterval($interval), \is_int($end) ? $end : new \DateTime($end), $options); Chris@12: $stub = new Stub(); Chris@12: Chris@17: $cast = DateCaster::castPeriod($p, [], $stub, false, 0); Chris@12: Chris@12: $xDump = << $xPeriod Chris@12: ] Chris@12: EODUMP; Chris@12: Chris@12: $this->assertDumpEquals($xDump, $cast); Chris@12: Chris@12: $xDump = <<assertDumpMatchesFormat($xDump, $cast["\0~\0period"]); Chris@12: } Chris@12: Chris@12: public function providePeriods() Chris@12: { Chris@12: $i = new \DateInterval('PT0S'); Chris@12: $ms = \PHP_VERSION_ID >= 70100 && isset($i->f) ? '.0' : ''; Chris@12: Chris@17: $periods = [ Chris@17: ['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'], Chris@17: ['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'], Chris@12: Chris@17: ['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'], Chris@17: ['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'], Chris@12: Chris@17: ['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'], Chris@17: ['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'], Chris@12: Chris@17: ['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'], Chris@17: ['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'], Chris@12: Chris@17: ['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'], Chris@17: ['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'], Chris@12: Chris@17: ['2017-01-01', 'P1DT1H', '2017-01-03', 0, "every + 1d 01:00:00$ms, 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'], Chris@17: ['2017-01-01', 'P1DT1H', 1, 0, "every + 1d 01:00:00$ms, 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'], Chris@12: Chris@17: ['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'], Chris@17: ['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'], Chris@17: ]; Chris@12: Chris@12: if (\PHP_VERSION_ID < 70107) { Chris@12: array_walk($periods, function (&$i) { $i[5] = ''; }); Chris@12: } Chris@12: Chris@12: return $periods; Chris@12: } Chris@12: Chris@12: private function createInterval($intervalSpec, $ms, $invert) Chris@12: { Chris@12: $interval = new \DateInterval($intervalSpec); Chris@12: if (\PHP_VERSION_ID >= 70100 && isset($interval->f)) { Chris@12: $interval->f = $ms; Chris@12: } Chris@12: $interval->invert = $invert; Chris@12: Chris@12: return $interval; Chris@12: } Chris@12: }