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 |
||
| 11 | class Test_Jetpack_JITM extends TestCase { |
||
| 12 | public function setUp() { |
||
| 13 | $this->mock_add_get_current_screen(); |
||
| 14 | $this->mock_add_action(); |
||
| 15 | $this->mock_do_action(); |
||
| 16 | $this->mock_wp_enqueue_script(); |
||
| 17 | |||
| 18 | // input/output of these functions doesn't matter right now, they just need to exist |
||
| 19 | $this->mock_empty_function( 'wp_register_style' ); |
||
| 20 | $this->mock_empty_function( 'plugins_url' ); |
||
| 21 | $this->mock_empty_function( 'wp_style_add_data' ); |
||
| 22 | $this->mock_empty_function( 'wp_enqueue_style' ); |
||
| 23 | $this->mock_empty_function( 'wp_localize_script' ); |
||
| 24 | $this->mock_empty_function( 'esc_url_raw' ); |
||
| 25 | $this->mock_empty_function( 'rest_url' ); |
||
| 26 | $this->mock_empty_function( 'esc_html__' ); |
||
| 27 | } |
||
| 28 | |||
| 29 | public function tearDown() { |
||
| 30 | Mock::disableAll(); |
||
| 31 | \Mockery::close(); |
||
| 32 | $this->clear_added_actions(); |
||
| 33 | $this->clear_enqueued_scripts(); |
||
| 34 | } |
||
| 35 | |||
| 36 | View Code Duplication | public function test_jitm_disabled_by_filter() { |
|
| 37 | $this->mock_filters( array( |
||
| 38 | array( 'jetpack_just_in_time_msgs', false, false ), |
||
| 39 | ) ); |
||
| 40 | |||
| 41 | $jitm = new JITM(); |
||
| 42 | $this->assertFalse( $jitm->register() ); |
||
| 43 | |||
| 44 | $this->clear_mock_filters(); |
||
| 45 | } |
||
| 46 | |||
| 47 | View Code Duplication | public function test_jitm_enabled_by_default() { |
|
| 48 | $this->mock_filters( array( |
||
| 49 | array( 'jetpack_just_in_time_msgs', false, true ), |
||
| 50 | ) ); |
||
| 51 | |||
| 52 | $jitm = new JITM(); |
||
| 53 | $this->assertTrue( $jitm->register() ); |
||
| 54 | |||
| 55 | $this->clear_mock_filters(); |
||
| 56 | } |
||
| 57 | |||
| 58 | /** |
||
| 59 | * This is an example of a test which uses Mockery to tests a class static method. |
||
| 60 | * |
||
| 61 | * It requires the runInSeparateProcess tag so that the class isn't already autoloaded. |
||
| 62 | * |
||
| 63 | * @runInSeparateProcess |
||
| 64 | */ |
||
| 65 | public function test_prepare_jitms_enqueues_assets() { |
||
| 66 | $mockAssets = \Mockery::mock('alias:Automattic\Jetpack\Assets'); |
||
| 67 | |||
| 68 | // mock the static method and return a dummy value |
||
| 69 | $mockAssets |
||
| 70 | ->shouldReceive('get_file_url_for_environment') |
||
| 71 | ->andReturn('the_file_url'); |
||
| 72 | |||
| 73 | $jitm = new JITM(); |
||
| 74 | $screen = (object) array( 'id' => 'jetpack_foo' ); // fake screen object |
||
| 75 | $jitm->prepare_jitms( $screen ); |
||
| 76 | |||
| 77 | // this should enqueue a jetpack-jitm-new script |
||
| 78 | do_action( 'admin_enqueue_scripts' ); |
||
| 79 | |||
| 80 | // assert our script was enqueued with the right value |
||
| 81 | $script = $this->get_enqueued_script( 'jetpack-jitm-new' ); |
||
| 82 | |||
| 83 | $this->assertEquals( 'the_file_url', $script['src'] ); |
||
| 84 | } |
||
| 85 | |||
| 86 | /* |
||
| 87 | public function test_prepare_jitms_does_not_show_on_some_screens() { |
||
| 88 | $jitm = new JITM(); |
||
| 89 | $screen = new \stdClass(); |
||
| 90 | $screen->id = 'jetpack_page_stats'; |
||
| 91 | $jitm->prepare_jitms( $screen ); |
||
| 92 | } |
||
| 93 | */ |
||
| 94 | |||
| 95 | protected function mock_filters( $filters ) { |
||
| 96 | $this->mocked_filters = $filters; |
||
| 97 | $builder = new MockBuilder(); |
||
| 98 | $builder->setNamespace( __NAMESPACE__ ) |
||
| 99 | ->setName( 'apply_filters' ) |
||
| 100 | ->setFunction( |
||
| 101 | function( ...$current_args ) { |
||
| 102 | foreach ( $this->mocked_filters as $filter ) { |
||
| 103 | if ( array_slice( $filter, 0, -1 ) === $current_args ) { |
||
| 104 | return array_pop( $filter ); |
||
| 105 | } |
||
| 106 | } |
||
| 107 | } |
||
| 108 | ); |
||
| 109 | $this->apply_filters_mock = $builder->build(); |
||
| 110 | $this->apply_filters_mock->enable(); |
||
| 111 | } |
||
| 112 | |||
| 113 | protected function clear_mock_filters() { |
||
| 117 | |||
| 118 | View Code Duplication | protected function mock_add_get_current_screen() { |
|
| 119 | $builder = new MockBuilder(); |
||
| 120 | $builder->setNamespace( __NAMESPACE__ ) |
||
| 121 | ->setName( 'get_current_screen' ) |
||
| 122 | ->setFunction( function() { |
||
| 123 | return new \stdClass; |
||
| 127 | |||
| 128 | protected function mock_add_action() { |
||
| 148 | |||
| 149 | protected function mock_do_action() { |
||
| 172 | |||
| 173 | protected function mock_wp_enqueue_script() { |
||
| 188 | |||
| 189 | protected function get_enqueued_script( $handle ) { |
||
| 193 | |||
| 194 | protected function clear_added_actions() { |
||
| 198 | |||
| 199 | protected function clear_enqueued_scripts() { |
||
| 203 | |||
| 204 | protected function mock_empty_function( $name ) { |
||
| 213 | } |
||
| 214 |