Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
| 1 | <?php |
||
| 6 | class procedural_api_Test extends ActionScheduler_UnitTestCase { |
||
| 7 | |||
| 8 | public function test_schedule_action() { |
||
| 9 | $time = time(); |
||
| 10 | $hook = md5(rand()); |
||
| 11 | $action_id = as_schedule_single_action( $time, $hook ); |
||
| 12 | |||
| 13 | $store = ActionScheduler::store(); |
||
| 14 | $action = $store->fetch_action($action_id); |
||
| 15 | $this->assertEquals( $time, $action->get_schedule()->next()->getTimestamp() ); |
||
| 16 | $this->assertEquals( $hook, $action->get_hook() ); |
||
| 17 | } |
||
| 18 | |||
| 19 | public function test_recurring_action() { |
||
| 20 | $time = time(); |
||
| 21 | $hook = md5(rand()); |
||
| 22 | $action_id = as_schedule_recurring_action( $time, HOUR_IN_SECONDS, $hook ); |
||
| 23 | |||
| 24 | $store = ActionScheduler::store(); |
||
| 25 | $action = $store->fetch_action($action_id); |
||
| 26 | $this->assertEquals( $time, $action->get_schedule()->next()->getTimestamp() ); |
||
| 27 | $this->assertEquals( $time + HOUR_IN_SECONDS + 2, $action->get_schedule()->next(as_get_datetime_object($time + 2))->getTimestamp()); |
||
| 28 | $this->assertEquals( $hook, $action->get_hook() ); |
||
| 29 | } |
||
| 30 | |||
| 31 | public function test_cron_schedule() { |
||
| 32 | $time = as_get_datetime_object('2014-01-01'); |
||
| 33 | $hook = md5(rand()); |
||
| 34 | $action_id = as_schedule_cron_action( $time->getTimestamp(), '0 0 10 10 *', $hook ); |
||
| 35 | |||
| 36 | $store = ActionScheduler::store(); |
||
| 37 | $action = $store->fetch_action($action_id); |
||
| 38 | $expected_date = as_get_datetime_object('2014-10-10'); |
||
| 39 | $this->assertEquals( $expected_date->getTimestamp(), $action->get_schedule()->next()->getTimestamp() ); |
||
| 40 | $this->assertEquals( $hook, $action->get_hook() ); |
||
| 41 | } |
||
| 42 | |||
| 43 | public function test_get_next() { |
||
| 44 | $time = as_get_datetime_object('tomorrow'); |
||
| 45 | $hook = md5(rand()); |
||
| 46 | as_schedule_recurring_action( $time->getTimestamp(), HOUR_IN_SECONDS, $hook ); |
||
| 47 | |||
| 48 | $next = as_next_scheduled_action( $hook ); |
||
| 49 | |||
| 50 | $this->assertEquals( $time->getTimestamp(), $next ); |
||
| 51 | } |
||
| 52 | |||
| 53 | public function provider_time_hook_args_group() { |
||
| 54 | $time = time() + 60 * 2; |
||
| 55 | $hook = md5( rand() ); |
||
| 56 | $args = array( rand(), rand() ); |
||
| 57 | $group = 'test_group'; |
||
| 58 | |||
| 59 | return array( |
||
| 60 | |||
| 61 | // Test with no args or group |
||
| 62 | array( |
||
| 63 | 'time' => $time, |
||
| 64 | 'hook' => $hook, |
||
| 65 | 'args' => array(), |
||
| 66 | 'group' => '', |
||
| 67 | ), |
||
| 68 | |||
| 69 | // Test with args but no group |
||
| 70 | array( |
||
| 71 | 'time' => $time, |
||
| 72 | 'hook' => $hook, |
||
| 73 | 'args' => $args, |
||
| 74 | 'group' => '', |
||
| 75 | ), |
||
| 76 | |||
| 77 | // Test with group but no args |
||
| 78 | array( |
||
| 79 | 'time' => $time, |
||
| 80 | 'hook' => $hook, |
||
| 81 | 'args' => array(), |
||
| 82 | 'group' => $group, |
||
| 83 | ), |
||
| 84 | |||
| 85 | // Test with args & group |
||
| 86 | array( |
||
| 87 | 'time' => $time, |
||
| 88 | 'hook' => $hook, |
||
| 89 | 'args' => $args, |
||
| 90 | 'group' => $group, |
||
| 91 | ), |
||
| 92 | ); |
||
| 93 | } |
||
| 94 | |||
| 95 | /** |
||
| 96 | * @dataProvider provider_time_hook_args_group |
||
| 97 | */ |
||
| 98 | public function test_unschedule( $time, $hook, $args, $group ) { |
||
| 99 | |||
| 100 | $action_id_unscheduled = as_schedule_single_action( $time, $hook, $args, $group ); |
||
| 101 | $action_scheduled_time = $time + 1; |
||
| 102 | $action_id_scheduled = as_schedule_single_action( $action_scheduled_time, $hook, $args, $group ); |
||
| 103 | |||
| 104 | as_unschedule_action( $hook, $args, $group ); |
||
| 105 | |||
| 106 | $next = as_next_scheduled_action( $hook, $args, $group ); |
||
| 107 | $this->assertEquals( $action_scheduled_time, $next ); |
||
| 108 | |||
| 109 | $store = ActionScheduler::store(); |
||
| 110 | $unscheduled_action = $store->fetch_action( $action_id_unscheduled ); |
||
| 111 | |||
| 112 | // Make sure the next scheduled action is unscheduled |
||
| 113 | $this->assertEquals( $hook, $unscheduled_action->get_hook() ); |
||
| 114 | $this->assertNull( $unscheduled_action->get_schedule()->next() ); |
||
| 115 | |||
| 116 | // Make sure other scheduled actions are not unscheduled |
||
| 117 | $scheduled_action = $store->fetch_action( $action_id_scheduled ); |
||
| 118 | |||
| 119 | $this->assertEquals( $hook, $scheduled_action->get_hook() ); |
||
| 120 | $this->assertEquals( $action_scheduled_time, $scheduled_action->get_schedule()->next()->getTimestamp() ); |
||
| 121 | } |
||
| 122 | |||
| 123 | /** |
||
| 124 | * @dataProvider provider_time_hook_args_group |
||
| 125 | */ |
||
| 126 | public function test_unschedule_all( $time, $hook, $args, $group ) { |
||
| 127 | |||
| 128 | $hook = md5( $hook ); |
||
| 129 | $action_ids = array(); |
||
| 130 | |||
| 131 | for ( $i = 0; $i < 3; $i++ ) { |
||
| 132 | $action_ids[] = as_schedule_single_action( $time, $hook, $args, $group ); |
||
| 133 | } |
||
| 134 | |||
| 135 | as_unschedule_all_actions( $hook, $args, $group ); |
||
| 136 | |||
| 137 | $next = as_next_scheduled_action( $hook ); |
||
| 138 | $this->assertFalse($next); |
||
| 139 | |||
| 140 | $store = ActionScheduler::store(); |
||
| 141 | |||
| 142 | foreach ( $action_ids as $action_id ) { |
||
| 143 | $action = $store->fetch_action($action_id); |
||
| 144 | |||
| 145 | $this->assertNull($action->get_schedule()->next()); |
||
| 146 | $this->assertEquals($hook, $action->get_hook() ); |
||
| 147 | } |
||
| 148 | } |
||
| 149 | |||
| 150 | public function test_as_get_datetime_object_default() { |
||
| 151 | |||
| 152 | $utc_now = new ActionScheduler_DateTime(null, new DateTimeZone('UTC')); |
||
| 153 | $as_now = as_get_datetime_object(); |
||
| 154 | |||
| 155 | // Don't want to use 'U' as timestamps will always be in UTC |
||
| 156 | $this->assertEquals($utc_now->format('Y-m-d H:i:s'),$as_now->format('Y-m-d H:i:s')); |
||
| 157 | } |
||
| 158 | |||
| 159 | public function test_as_get_datetime_object_relative() { |
||
| 160 | |||
| 161 | $utc_tomorrow = new ActionScheduler_DateTime('tomorrow', new DateTimeZone('UTC')); |
||
| 162 | $as_tomorrow = as_get_datetime_object('tomorrow'); |
||
| 163 | |||
| 164 | $this->assertEquals($utc_tomorrow->format('Y-m-d H:i:s'),$as_tomorrow->format('Y-m-d H:i:s')); |
||
| 165 | |||
| 166 | $utc_tomorrow = new ActionScheduler_DateTime('yesterday', new DateTimeZone('UTC')); |
||
| 167 | $as_tomorrow = as_get_datetime_object('yesterday'); |
||
| 168 | |||
| 169 | $this->assertEquals($utc_tomorrow->format('Y-m-d H:i:s'),$as_tomorrow->format('Y-m-d H:i:s')); |
||
| 170 | } |
||
| 171 | |||
| 172 | public function test_as_get_datetime_object_fixed() { |
||
| 173 | |||
| 174 | $utc_tomorrow = new ActionScheduler_DateTime('29 February 2016', new DateTimeZone('UTC')); |
||
| 175 | $as_tomorrow = as_get_datetime_object('29 February 2016'); |
||
| 176 | |||
| 177 | $this->assertEquals($utc_tomorrow->format('Y-m-d H:i:s'),$as_tomorrow->format('Y-m-d H:i:s')); |
||
| 178 | |||
| 179 | $utc_tomorrow = new ActionScheduler_DateTime('1st January 2024', new DateTimeZone('UTC')); |
||
| 180 | $as_tomorrow = as_get_datetime_object('1st January 2024'); |
||
| 181 | |||
| 182 | $this->assertEquals($utc_tomorrow->format('Y-m-d H:i:s'),$as_tomorrow->format('Y-m-d H:i:s')); |
||
| 183 | } |
||
| 184 | |||
| 185 | public function test_as_get_datetime_object_timezone() { |
||
| 186 | |||
| 187 | $timezone_au = 'Australia/Brisbane'; |
||
| 188 | $timezone_default = date_default_timezone_get(); |
||
| 189 | |||
| 190 | date_default_timezone_set( $timezone_au ); |
||
| 191 | |||
| 192 | $au_now = new ActionScheduler_DateTime(null); |
||
| 193 | $as_now = as_get_datetime_object(); |
||
| 194 | |||
| 195 | // Make sure they're for the same time |
||
| 196 | $this->assertEquals($au_now->getTimestamp(),$as_now->getTimestamp()); |
||
| 197 | |||
| 198 | // But not in the same timezone, as $as_now should be using UTC |
||
| 199 | $this->assertNotEquals($au_now->format('Y-m-d H:i:s'),$as_now->format('Y-m-d H:i:s')); |
||
| 200 | |||
| 201 | $au_now = new ActionScheduler_DateTime(null); |
||
| 202 | $as_au_now = as_get_datetime_object(); |
||
| 203 | |||
| 204 | $this->assertEquals($au_now->getTimestamp(),$as_now->getTimestamp()); |
||
| 205 | |||
| 206 | // But not in the same timezone, as $as_now should be using UTC |
||
| 207 | $this->assertNotEquals($au_now->format('Y-m-d H:i:s'),$as_now->format('Y-m-d H:i:s')); |
||
| 208 | |||
| 209 | // Just in cases |
||
| 210 | date_default_timezone_set( $timezone_default ); |
||
| 211 | } |
||
| 212 | |||
| 213 | public function test_as_get_datetime_object_type() { |
||
| 214 | $f = 'Y-m-d H:i:s'; |
||
| 215 | $now = as_get_datetime_object(); |
||
| 216 | $this->assertInstanceOf( 'ActionScheduler_DateTime', $now ); |
||
| 217 | |||
| 218 | $dateTime = new DateTime( 'now', new DateTimeZone( 'UTC' ) ); |
||
| 219 | $asDateTime = as_get_datetime_object( $dateTime ); |
||
| 220 | $this->assertEquals( $dateTime->format( $f ), $asDateTime->format( $f ) ); |
||
| 221 | } |
||
| 222 | } |
||
| 223 |