1*37748cd8SNickeau<?php 2*37748cd8SNickeau 3*37748cd8SNickeaunamespace Cron\Tests; 4*37748cd8SNickeau 5*37748cd8SNickeauuse Cron\CronExpression; 6*37748cd8SNickeauuse DateTime; 7*37748cd8SNickeauuse DateTimeZone; 8*37748cd8SNickeauuse InvalidArgumentException; 9*37748cd8SNickeauuse PHPUnit_Framework_TestCase; 10*37748cd8SNickeau 11*37748cd8SNickeau/** 12*37748cd8SNickeau * @author Michael Dowling <mtdowling@gmail.com> 13*37748cd8SNickeau */ 14*37748cd8SNickeauclass CronExpressionTest extends PHPUnit_Framework_TestCase 15*37748cd8SNickeau{ 16*37748cd8SNickeau /** 17*37748cd8SNickeau * @covers Cron\CronExpression::factory 18*37748cd8SNickeau */ 19*37748cd8SNickeau public function testFactoryRecognizesTemplates() 20*37748cd8SNickeau { 21*37748cd8SNickeau $this->assertEquals('0 0 1 1 *', CronExpression::factory('@annually')->getExpression()); 22*37748cd8SNickeau $this->assertEquals('0 0 1 1 *', CronExpression::factory('@yearly')->getExpression()); 23*37748cd8SNickeau $this->assertEquals('0 0 * * 0', CronExpression::factory('@weekly')->getExpression()); 24*37748cd8SNickeau } 25*37748cd8SNickeau 26*37748cd8SNickeau /** 27*37748cd8SNickeau * @covers Cron\CronExpression::__construct 28*37748cd8SNickeau * @covers Cron\CronExpression::getExpression 29*37748cd8SNickeau * @covers Cron\CronExpression::__toString 30*37748cd8SNickeau */ 31*37748cd8SNickeau public function testParsesCronSchedule() 32*37748cd8SNickeau { 33*37748cd8SNickeau // '2010-09-10 12:00:00' 34*37748cd8SNickeau $cron = CronExpression::factory('1 2-4 * 4,5,6 */3'); 35*37748cd8SNickeau $this->assertEquals('1', $cron->getExpression(CronExpression::MINUTE)); 36*37748cd8SNickeau $this->assertEquals('2-4', $cron->getExpression(CronExpression::HOUR)); 37*37748cd8SNickeau $this->assertEquals('*', $cron->getExpression(CronExpression::DAY)); 38*37748cd8SNickeau $this->assertEquals('4,5,6', $cron->getExpression(CronExpression::MONTH)); 39*37748cd8SNickeau $this->assertEquals('*/3', $cron->getExpression(CronExpression::WEEKDAY)); 40*37748cd8SNickeau $this->assertEquals('1 2-4 * 4,5,6 */3', $cron->getExpression()); 41*37748cd8SNickeau $this->assertEquals('1 2-4 * 4,5,6 */3', (string) $cron); 42*37748cd8SNickeau $this->assertNull($cron->getExpression('foo')); 43*37748cd8SNickeau 44*37748cd8SNickeau try { 45*37748cd8SNickeau $cron = CronExpression::factory('A 1 2 3 4'); 46*37748cd8SNickeau $this->fail('Validation exception not thrown'); 47*37748cd8SNickeau } catch (InvalidArgumentException $e) { 48*37748cd8SNickeau } 49*37748cd8SNickeau } 50*37748cd8SNickeau 51*37748cd8SNickeau /** 52*37748cd8SNickeau * @covers Cron\CronExpression::__construct 53*37748cd8SNickeau * @covers Cron\CronExpression::getExpression 54*37748cd8SNickeau * @dataProvider scheduleWithDifferentSeparatorsProvider 55*37748cd8SNickeau */ 56*37748cd8SNickeau public function testParsesCronScheduleWithAnySpaceCharsAsSeparators($schedule, array $expected) 57*37748cd8SNickeau { 58*37748cd8SNickeau $cron = CronExpression::factory($schedule); 59*37748cd8SNickeau $this->assertEquals($expected[0], $cron->getExpression(CronExpression::MINUTE)); 60*37748cd8SNickeau $this->assertEquals($expected[1], $cron->getExpression(CronExpression::HOUR)); 61*37748cd8SNickeau $this->assertEquals($expected[2], $cron->getExpression(CronExpression::DAY)); 62*37748cd8SNickeau $this->assertEquals($expected[3], $cron->getExpression(CronExpression::MONTH)); 63*37748cd8SNickeau $this->assertEquals($expected[4], $cron->getExpression(CronExpression::WEEKDAY)); 64*37748cd8SNickeau $this->assertEquals($expected[5], $cron->getExpression(CronExpression::YEAR)); 65*37748cd8SNickeau } 66*37748cd8SNickeau 67*37748cd8SNickeau /** 68*37748cd8SNickeau * Data provider for testParsesCronScheduleWithAnySpaceCharsAsSeparators 69*37748cd8SNickeau * 70*37748cd8SNickeau * @return array 71*37748cd8SNickeau */ 72*37748cd8SNickeau public static function scheduleWithDifferentSeparatorsProvider() 73*37748cd8SNickeau { 74*37748cd8SNickeau return array( 75*37748cd8SNickeau array("*\t*\t*\t*\t*\t*", array('*', '*', '*', '*', '*', '*')), 76*37748cd8SNickeau array("* * * * * *", array('*', '*', '*', '*', '*', '*')), 77*37748cd8SNickeau array("* \t * \t * \t * \t * \t *", array('*', '*', '*', '*', '*', '*')), 78*37748cd8SNickeau array("*\t \t*\t \t*\t \t*\t \t*\t \t*", array('*', '*', '*', '*', '*', '*')), 79*37748cd8SNickeau ); 80*37748cd8SNickeau } 81*37748cd8SNickeau 82*37748cd8SNickeau /** 83*37748cd8SNickeau * @covers Cron\CronExpression::__construct 84*37748cd8SNickeau * @covers Cron\CronExpression::setExpression 85*37748cd8SNickeau * @covers Cron\CronExpression::setPart 86*37748cd8SNickeau * @expectedException InvalidArgumentException 87*37748cd8SNickeau */ 88*37748cd8SNickeau public function testInvalidCronsWillFail() 89*37748cd8SNickeau { 90*37748cd8SNickeau // Only four values 91*37748cd8SNickeau $cron = CronExpression::factory('* * * 1'); 92*37748cd8SNickeau } 93*37748cd8SNickeau 94*37748cd8SNickeau /** 95*37748cd8SNickeau * @covers Cron\CronExpression::setPart 96*37748cd8SNickeau * @expectedException InvalidArgumentException 97*37748cd8SNickeau */ 98*37748cd8SNickeau public function testInvalidPartsWillFail() 99*37748cd8SNickeau { 100*37748cd8SNickeau // Only four values 101*37748cd8SNickeau $cron = CronExpression::factory('* * * * *'); 102*37748cd8SNickeau $cron->setPart(1, 'abc'); 103*37748cd8SNickeau } 104*37748cd8SNickeau 105*37748cd8SNickeau /** 106*37748cd8SNickeau * Data provider for cron schedule 107*37748cd8SNickeau * 108*37748cd8SNickeau * @return array 109*37748cd8SNickeau */ 110*37748cd8SNickeau public function scheduleProvider() 111*37748cd8SNickeau { 112*37748cd8SNickeau return array( 113*37748cd8SNickeau array('*/2 */2 * * *', '2015-08-10 21:47:27', '2015-08-10 22:00:00', false), 114*37748cd8SNickeau array('* * * * *', '2015-08-10 21:50:37', '2015-08-10 21:50:00', true), 115*37748cd8SNickeau array('* 20,21,22 * * *', '2015-08-10 21:50:00', '2015-08-10 21:50:00', true), 116*37748cd8SNickeau // Handles CSV values 117*37748cd8SNickeau array('* 20,22 * * *', '2015-08-10 21:50:00', '2015-08-10 22:00:00', false), 118*37748cd8SNickeau // CSV values can be complex 119*37748cd8SNickeau array('* 5,21-22 * * *', '2015-08-10 21:50:00', '2015-08-10 21:50:00', true), 120*37748cd8SNickeau array('7-9 * */9 * *', '2015-08-10 22:02:33', '2015-08-18 00:07:00', false), 121*37748cd8SNickeau // 15th minute, of the second hour, every 15 days, in January, every Friday 122*37748cd8SNickeau array('1 * * * 7', '2015-08-10 21:47:27', '2015-08-16 00:01:00', false), 123*37748cd8SNickeau // Test with exact times 124*37748cd8SNickeau array('47 21 * * *', strtotime('2015-08-10 21:47:30'), '2015-08-10 21:47:00', true), 125*37748cd8SNickeau // Test Day of the week (issue #1) 126*37748cd8SNickeau // According cron implementation, 0|7 = sunday, 1 => monday, etc 127*37748cd8SNickeau array('* * * * 0', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), 128*37748cd8SNickeau array('* * * * 7', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), 129*37748cd8SNickeau array('* * * * 1', strtotime('2011-06-15 23:09:00'), '2011-06-20 00:00:00', false), 130*37748cd8SNickeau // Should return the sunday date as 7 equals 0 131*37748cd8SNickeau array('0 0 * * MON,SUN', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), 132*37748cd8SNickeau array('0 0 * * 1,7', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), 133*37748cd8SNickeau array('0 0 * * 0-4', strtotime('2011-06-15 23:09:00'), '2011-06-16 00:00:00', false), 134*37748cd8SNickeau array('0 0 * * 7-4', strtotime('2011-06-15 23:09:00'), '2011-06-16 00:00:00', false), 135*37748cd8SNickeau array('0 0 * * 4-7', strtotime('2011-06-15 23:09:00'), '2011-06-16 00:00:00', false), 136*37748cd8SNickeau array('0 0 * * 7-3', strtotime('2011-06-15 23:09:00'), '2011-06-19 00:00:00', false), 137*37748cd8SNickeau array('0 0 * * 3-7', strtotime('2011-06-15 23:09:00'), '2011-06-16 00:00:00', false), 138*37748cd8SNickeau array('0 0 * * 3-7', strtotime('2011-06-18 23:09:00'), '2011-06-19 00:00:00', false), 139*37748cd8SNickeau // Test lists of values and ranges (Abhoryo) 140*37748cd8SNickeau array('0 0 * * 2-7', strtotime('2011-06-20 23:09:00'), '2011-06-21 00:00:00', false), 141*37748cd8SNickeau array('0 0 * * 0,2-6', strtotime('2011-06-20 23:09:00'), '2011-06-21 00:00:00', false), 142*37748cd8SNickeau array('0 0 * * 2-7', strtotime('2011-06-18 23:09:00'), '2011-06-19 00:00:00', false), 143*37748cd8SNickeau array('0 0 * * 4-7', strtotime('2011-07-19 00:00:00'), '2011-07-21 00:00:00', false), 144*37748cd8SNickeau // Test increments of ranges 145*37748cd8SNickeau array('0-12/4 * * * *', strtotime('2011-06-20 12:04:00'), '2011-06-20 12:04:00', true), 146*37748cd8SNickeau array('4-59/2 * * * *', strtotime('2011-06-20 12:04:00'), '2011-06-20 12:04:00', true), 147*37748cd8SNickeau array('4-59/2 * * * *', strtotime('2011-06-20 12:06:00'), '2011-06-20 12:06:00', true), 148*37748cd8SNickeau array('4-59/3 * * * *', strtotime('2011-06-20 12:06:00'), '2011-06-20 12:07:00', false), 149*37748cd8SNickeau //array('0 0 * * 0,2-6', strtotime('2011-06-20 23:09:00'), '2011-06-21 00:00:00', false), 150*37748cd8SNickeau // Test Day of the Week and the Day of the Month (issue #1) 151*37748cd8SNickeau array('0 0 1 1 0', strtotime('2011-06-15 23:09:00'), '2012-01-01 00:00:00', false), 152*37748cd8SNickeau array('0 0 1 JAN 0', strtotime('2011-06-15 23:09:00'), '2012-01-01 00:00:00', false), 153*37748cd8SNickeau array('0 0 1 * 0', strtotime('2011-06-15 23:09:00'), '2012-01-01 00:00:00', false), 154*37748cd8SNickeau array('0 0 L * *', strtotime('2011-07-15 00:00:00'), '2011-07-31 00:00:00', false), 155*37748cd8SNickeau // Test the W day of the week modifier for day of the month field 156*37748cd8SNickeau array('0 0 2W * *', strtotime('2011-07-01 00:00:00'), '2011-07-01 00:00:00', true), 157*37748cd8SNickeau array('0 0 1W * *', strtotime('2011-05-01 00:00:00'), '2011-05-02 00:00:00', false), 158*37748cd8SNickeau array('0 0 1W * *', strtotime('2011-07-01 00:00:00'), '2011-07-01 00:00:00', true), 159*37748cd8SNickeau array('0 0 3W * *', strtotime('2011-07-01 00:00:00'), '2011-07-04 00:00:00', false), 160*37748cd8SNickeau array('0 0 16W * *', strtotime('2011-07-01 00:00:00'), '2011-07-15 00:00:00', false), 161*37748cd8SNickeau array('0 0 28W * *', strtotime('2011-07-01 00:00:00'), '2011-07-28 00:00:00', false), 162*37748cd8SNickeau array('0 0 30W * *', strtotime('2011-07-01 00:00:00'), '2011-07-29 00:00:00', false), 163*37748cd8SNickeau array('0 0 31W * *', strtotime('2011-07-01 00:00:00'), '2011-07-29 00:00:00', false), 164*37748cd8SNickeau // Test the year field 165*37748cd8SNickeau array('* * * * * 2012', strtotime('2011-05-01 00:00:00'), '2012-01-01 00:00:00', false), 166*37748cd8SNickeau // Test the last weekday of a month 167*37748cd8SNickeau array('* * * * 5L', strtotime('2011-07-01 00:00:00'), '2011-07-29 00:00:00', false), 168*37748cd8SNickeau array('* * * * 6L', strtotime('2011-07-01 00:00:00'), '2011-07-30 00:00:00', false), 169*37748cd8SNickeau array('* * * * 7L', strtotime('2011-07-01 00:00:00'), '2011-07-31 00:00:00', false), 170*37748cd8SNickeau array('* * * * 1L', strtotime('2011-07-24 00:00:00'), '2011-07-25 00:00:00', false), 171*37748cd8SNickeau array('* * * * TUEL', strtotime('2011-07-24 00:00:00'), '2011-07-26 00:00:00', false), 172*37748cd8SNickeau array('* * * 1 5L', strtotime('2011-12-25 00:00:00'), '2012-01-27 00:00:00', false), 173*37748cd8SNickeau // Test the hash symbol for the nth weekday of a given month 174*37748cd8SNickeau array('* * * * 5#2', strtotime('2011-07-01 00:00:00'), '2011-07-08 00:00:00', false), 175*37748cd8SNickeau array('* * * * 5#1', strtotime('2011-07-01 00:00:00'), '2011-07-01 00:00:00', true), 176*37748cd8SNickeau array('* * * * 3#4', strtotime('2011-07-01 00:00:00'), '2011-07-27 00:00:00', false), 177*37748cd8SNickeau ); 178*37748cd8SNickeau } 179*37748cd8SNickeau 180*37748cd8SNickeau /** 181*37748cd8SNickeau * @covers Cron\CronExpression::isDue 182*37748cd8SNickeau * @covers Cron\CronExpression::getNextRunDate 183*37748cd8SNickeau * @covers Cron\DayOfMonthField 184*37748cd8SNickeau * @covers Cron\DayOfWeekField 185*37748cd8SNickeau * @covers Cron\MinutesField 186*37748cd8SNickeau * @covers Cron\HoursField 187*37748cd8SNickeau * @covers Cron\MonthField 188*37748cd8SNickeau * @covers Cron\YearField 189*37748cd8SNickeau * @covers Cron\CronExpression::getRunDate 190*37748cd8SNickeau * @dataProvider scheduleProvider 191*37748cd8SNickeau */ 192*37748cd8SNickeau public function testDeterminesIfCronIsDue($schedule, $relativeTime, $nextRun, $isDue) 193*37748cd8SNickeau { 194*37748cd8SNickeau $relativeTimeString = is_int($relativeTime) ? date('Y-m-d H:i:s', $relativeTime) : $relativeTime; 195*37748cd8SNickeau 196*37748cd8SNickeau // Test next run date 197*37748cd8SNickeau $cron = CronExpression::factory($schedule); 198*37748cd8SNickeau if (is_string($relativeTime)) { 199*37748cd8SNickeau $relativeTime = new DateTime($relativeTime); 200*37748cd8SNickeau } elseif (is_int($relativeTime)) { 201*37748cd8SNickeau $relativeTime = date('Y-m-d H:i:s', $relativeTime); 202*37748cd8SNickeau } 203*37748cd8SNickeau $this->assertEquals($isDue, $cron->isDue($relativeTime)); 204*37748cd8SNickeau $next = $cron->getNextRunDate($relativeTime, 0, true); 205*37748cd8SNickeau $this->assertEquals(new DateTime($nextRun), $next); 206*37748cd8SNickeau } 207*37748cd8SNickeau 208*37748cd8SNickeau /** 209*37748cd8SNickeau * @covers Cron\CronExpression::isDue 210*37748cd8SNickeau */ 211*37748cd8SNickeau public function testIsDueHandlesDifferentDates() 212*37748cd8SNickeau { 213*37748cd8SNickeau $cron = CronExpression::factory('* * * * *'); 214*37748cd8SNickeau $this->assertTrue($cron->isDue()); 215*37748cd8SNickeau $this->assertTrue($cron->isDue('now')); 216*37748cd8SNickeau $this->assertTrue($cron->isDue(new DateTime('now'))); 217*37748cd8SNickeau $this->assertTrue($cron->isDue(date('Y-m-d H:i'))); 218*37748cd8SNickeau } 219*37748cd8SNickeau 220*37748cd8SNickeau /** 221*37748cd8SNickeau * @covers Cron\CronExpression::isDue 222*37748cd8SNickeau */ 223*37748cd8SNickeau public function testIsDueHandlesDifferentTimezones() 224*37748cd8SNickeau { 225*37748cd8SNickeau $cron = CronExpression::factory('0 15 * * 3'); //Wednesday at 15:00 226*37748cd8SNickeau $date = '2014-01-01 15:00'; //Wednesday 227*37748cd8SNickeau $utc = new DateTimeZone('UTC'); 228*37748cd8SNickeau $amsterdam = new DateTimeZone('Europe/Amsterdam'); 229*37748cd8SNickeau $tokyo = new DateTimeZone('Asia/Tokyo'); 230*37748cd8SNickeau 231*37748cd8SNickeau date_default_timezone_set('UTC'); 232*37748cd8SNickeau $this->assertTrue($cron->isDue(new DateTime($date, $utc))); 233*37748cd8SNickeau $this->assertFalse($cron->isDue(new DateTime($date, $amsterdam))); 234*37748cd8SNickeau $this->assertFalse($cron->isDue(new DateTime($date, $tokyo))); 235*37748cd8SNickeau 236*37748cd8SNickeau date_default_timezone_set('Europe/Amsterdam'); 237*37748cd8SNickeau $this->assertFalse($cron->isDue(new DateTime($date, $utc))); 238*37748cd8SNickeau $this->assertTrue($cron->isDue(new DateTime($date, $amsterdam))); 239*37748cd8SNickeau $this->assertFalse($cron->isDue(new DateTime($date, $tokyo))); 240*37748cd8SNickeau 241*37748cd8SNickeau date_default_timezone_set('Asia/Tokyo'); 242*37748cd8SNickeau $this->assertFalse($cron->isDue(new DateTime($date, $utc))); 243*37748cd8SNickeau $this->assertFalse($cron->isDue(new DateTime($date, $amsterdam))); 244*37748cd8SNickeau $this->assertTrue($cron->isDue(new DateTime($date, $tokyo))); 245*37748cd8SNickeau } 246*37748cd8SNickeau 247*37748cd8SNickeau /** 248*37748cd8SNickeau * @covers Cron\CronExpression::getPreviousRunDate 249*37748cd8SNickeau */ 250*37748cd8SNickeau public function testCanGetPreviousRunDates() 251*37748cd8SNickeau { 252*37748cd8SNickeau $cron = CronExpression::factory('* * * * *'); 253*37748cd8SNickeau $next = $cron->getNextRunDate('now'); 254*37748cd8SNickeau $two = $cron->getNextRunDate('now', 1); 255*37748cd8SNickeau $this->assertEquals($next, $cron->getPreviousRunDate($two)); 256*37748cd8SNickeau 257*37748cd8SNickeau $cron = CronExpression::factory('* */2 * * *'); 258*37748cd8SNickeau $next = $cron->getNextRunDate('now'); 259*37748cd8SNickeau $two = $cron->getNextRunDate('now', 1); 260*37748cd8SNickeau $this->assertEquals($next, $cron->getPreviousRunDate($two)); 261*37748cd8SNickeau 262*37748cd8SNickeau $cron = CronExpression::factory('* * * */2 *'); 263*37748cd8SNickeau $next = $cron->getNextRunDate('now'); 264*37748cd8SNickeau $two = $cron->getNextRunDate('now', 1); 265*37748cd8SNickeau $this->assertEquals($next, $cron->getPreviousRunDate($two)); 266*37748cd8SNickeau } 267*37748cd8SNickeau 268*37748cd8SNickeau /** 269*37748cd8SNickeau * @covers Cron\CronExpression::getMultipleRunDates 270*37748cd8SNickeau */ 271*37748cd8SNickeau public function testProvidesMultipleRunDates() 272*37748cd8SNickeau { 273*37748cd8SNickeau $cron = CronExpression::factory('*/2 * * * *'); 274*37748cd8SNickeau $this->assertEquals(array( 275*37748cd8SNickeau new DateTime('2008-11-09 00:00:00'), 276*37748cd8SNickeau new DateTime('2008-11-09 00:02:00'), 277*37748cd8SNickeau new DateTime('2008-11-09 00:04:00'), 278*37748cd8SNickeau new DateTime('2008-11-09 00:06:00') 279*37748cd8SNickeau ), $cron->getMultipleRunDates(4, '2008-11-09 00:00:00', false, true)); 280*37748cd8SNickeau } 281*37748cd8SNickeau 282*37748cd8SNickeau /** 283*37748cd8SNickeau * @covers Cron\CronExpression::getMultipleRunDates 284*37748cd8SNickeau * @covers Cron\CronExpression::setMaxIterationCount 285*37748cd8SNickeau */ 286*37748cd8SNickeau public function testProvidesMultipleRunDatesForTheFarFuture() { 287*37748cd8SNickeau // Fails with the default 1000 iteration limit 288*37748cd8SNickeau $cron = CronExpression::factory('0 0 12 1 * */2'); 289*37748cd8SNickeau $cron->setMaxIterationCount(2000); 290*37748cd8SNickeau $this->assertEquals(array( 291*37748cd8SNickeau new DateTime('2016-01-12 00:00:00'), 292*37748cd8SNickeau new DateTime('2018-01-12 00:00:00'), 293*37748cd8SNickeau new DateTime('2020-01-12 00:00:00'), 294*37748cd8SNickeau new DateTime('2022-01-12 00:00:00'), 295*37748cd8SNickeau new DateTime('2024-01-12 00:00:00'), 296*37748cd8SNickeau new DateTime('2026-01-12 00:00:00'), 297*37748cd8SNickeau new DateTime('2028-01-12 00:00:00'), 298*37748cd8SNickeau new DateTime('2030-01-12 00:00:00'), 299*37748cd8SNickeau new DateTime('2032-01-12 00:00:00'), 300*37748cd8SNickeau ), $cron->getMultipleRunDates(9, '2015-04-28 00:00:00', false, true)); 301*37748cd8SNickeau } 302*37748cd8SNickeau 303*37748cd8SNickeau /** 304*37748cd8SNickeau * @covers Cron\CronExpression 305*37748cd8SNickeau */ 306*37748cd8SNickeau public function testCanIterateOverNextRuns() 307*37748cd8SNickeau { 308*37748cd8SNickeau $cron = CronExpression::factory('@weekly'); 309*37748cd8SNickeau $nextRun = $cron->getNextRunDate("2008-11-09 08:00:00"); 310*37748cd8SNickeau $this->assertEquals($nextRun, new DateTime("2008-11-16 00:00:00")); 311*37748cd8SNickeau 312*37748cd8SNickeau // true is cast to 1 313*37748cd8SNickeau $nextRun = $cron->getNextRunDate("2008-11-09 00:00:00", true, true); 314*37748cd8SNickeau $this->assertEquals($nextRun, new DateTime("2008-11-16 00:00:00")); 315*37748cd8SNickeau 316*37748cd8SNickeau // You can iterate over them 317*37748cd8SNickeau $nextRun = $cron->getNextRunDate($cron->getNextRunDate("2008-11-09 00:00:00", 1, true), 1, true); 318*37748cd8SNickeau $this->assertEquals($nextRun, new DateTime("2008-11-23 00:00:00")); 319*37748cd8SNickeau 320*37748cd8SNickeau // You can skip more than one 321*37748cd8SNickeau $nextRun = $cron->getNextRunDate("2008-11-09 00:00:00", 2, true); 322*37748cd8SNickeau $this->assertEquals($nextRun, new DateTime("2008-11-23 00:00:00")); 323*37748cd8SNickeau $nextRun = $cron->getNextRunDate("2008-11-09 00:00:00", 3, true); 324*37748cd8SNickeau $this->assertEquals($nextRun, new DateTime("2008-11-30 00:00:00")); 325*37748cd8SNickeau } 326*37748cd8SNickeau 327*37748cd8SNickeau /** 328*37748cd8SNickeau * @covers Cron\CronExpression::getRunDate 329*37748cd8SNickeau */ 330*37748cd8SNickeau public function testSkipsCurrentDateByDefault() 331*37748cd8SNickeau { 332*37748cd8SNickeau $cron = CronExpression::factory('* * * * *'); 333*37748cd8SNickeau $current = new DateTime('now'); 334*37748cd8SNickeau $next = $cron->getNextRunDate($current); 335*37748cd8SNickeau $nextPrev = $cron->getPreviousRunDate($next); 336*37748cd8SNickeau $this->assertEquals($current->format('Y-m-d H:i:00'), $nextPrev->format('Y-m-d H:i:s')); 337*37748cd8SNickeau } 338*37748cd8SNickeau 339*37748cd8SNickeau /** 340*37748cd8SNickeau * @covers Cron\CronExpression::getRunDate 341*37748cd8SNickeau * @ticket 7 342*37748cd8SNickeau */ 343*37748cd8SNickeau public function testStripsForSeconds() 344*37748cd8SNickeau { 345*37748cd8SNickeau $cron = CronExpression::factory('* * * * *'); 346*37748cd8SNickeau $current = new DateTime('2011-09-27 10:10:54'); 347*37748cd8SNickeau $this->assertEquals('2011-09-27 10:11:00', $cron->getNextRunDate($current)->format('Y-m-d H:i:s')); 348*37748cd8SNickeau } 349*37748cd8SNickeau 350*37748cd8SNickeau /** 351*37748cd8SNickeau * @covers Cron\CronExpression::getRunDate 352*37748cd8SNickeau */ 353*37748cd8SNickeau public function testFixesPhpBugInDateIntervalMonth() 354*37748cd8SNickeau { 355*37748cd8SNickeau $cron = CronExpression::factory('0 0 27 JAN *'); 356*37748cd8SNickeau $this->assertEquals('2011-01-27 00:00:00', $cron->getPreviousRunDate('2011-08-22 00:00:00')->format('Y-m-d H:i:s')); 357*37748cd8SNickeau } 358*37748cd8SNickeau 359*37748cd8SNickeau public function testIssue29() 360*37748cd8SNickeau { 361*37748cd8SNickeau $cron = CronExpression::factory('@weekly'); 362*37748cd8SNickeau $this->assertEquals( 363*37748cd8SNickeau '2013-03-10 00:00:00', 364*37748cd8SNickeau $cron->getPreviousRunDate('2013-03-17 00:00:00')->format('Y-m-d H:i:s') 365*37748cd8SNickeau ); 366*37748cd8SNickeau } 367*37748cd8SNickeau 368*37748cd8SNickeau /** 369*37748cd8SNickeau * @see https://github.com/mtdowling/cron-expression/issues/20 370*37748cd8SNickeau */ 371*37748cd8SNickeau public function testIssue20() { 372*37748cd8SNickeau $e = CronExpression::factory('* * * * MON#1'); 373*37748cd8SNickeau $this->assertTrue($e->isDue(new DateTime('2014-04-07 00:00:00'))); 374*37748cd8SNickeau $this->assertFalse($e->isDue(new DateTime('2014-04-14 00:00:00'))); 375*37748cd8SNickeau $this->assertFalse($e->isDue(new DateTime('2014-04-21 00:00:00'))); 376*37748cd8SNickeau 377*37748cd8SNickeau $e = CronExpression::factory('* * * * SAT#2'); 378*37748cd8SNickeau $this->assertFalse($e->isDue(new DateTime('2014-04-05 00:00:00'))); 379*37748cd8SNickeau $this->assertTrue($e->isDue(new DateTime('2014-04-12 00:00:00'))); 380*37748cd8SNickeau $this->assertFalse($e->isDue(new DateTime('2014-04-19 00:00:00'))); 381*37748cd8SNickeau 382*37748cd8SNickeau $e = CronExpression::factory('* * * * SUN#3'); 383*37748cd8SNickeau $this->assertFalse($e->isDue(new DateTime('2014-04-13 00:00:00'))); 384*37748cd8SNickeau $this->assertTrue($e->isDue(new DateTime('2014-04-20 00:00:00'))); 385*37748cd8SNickeau $this->assertFalse($e->isDue(new DateTime('2014-04-27 00:00:00'))); 386*37748cd8SNickeau } 387*37748cd8SNickeau 388*37748cd8SNickeau /** 389*37748cd8SNickeau * @covers Cron\CronExpression::getRunDate 390*37748cd8SNickeau */ 391*37748cd8SNickeau public function testKeepOriginalTime() 392*37748cd8SNickeau { 393*37748cd8SNickeau $now = new \DateTime; 394*37748cd8SNickeau $strNow = $now->format(DateTime::ISO8601); 395*37748cd8SNickeau $cron = CronExpression::factory('0 0 * * *'); 396*37748cd8SNickeau $cron->getPreviousRunDate($now); 397*37748cd8SNickeau $this->assertEquals($strNow, $now->format(DateTime::ISO8601)); 398*37748cd8SNickeau } 399*37748cd8SNickeau 400*37748cd8SNickeau /** 401*37748cd8SNickeau * @covers Cron\CronExpression::__construct 402*37748cd8SNickeau * @covers Cron\CronExpression::factory 403*37748cd8SNickeau * @covers Cron\CronExpression::isValidExpression 404*37748cd8SNickeau * @covers Cron\CronExpression::setExpression 405*37748cd8SNickeau * @covers Cron\CronExpression::setPart 406*37748cd8SNickeau */ 407*37748cd8SNickeau public function testValidationWorks() 408*37748cd8SNickeau { 409*37748cd8SNickeau // Invalid. Only four values 410*37748cd8SNickeau $this->assertFalse(CronExpression::isValidExpression('* * * 1')); 411*37748cd8SNickeau // Valid 412*37748cd8SNickeau $this->assertTrue(CronExpression::isValidExpression('* * * * 1')); 413*37748cd8SNickeau } 414*37748cd8SNickeau} 415