Completed
Push — add/jetpack-assistant-ui ( a6f776...33ce41 )
by Jeremy
202:03 queued 191:10
created

Test_PHP_Autoloader   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 89
Duplicated Lines 35.96 %

Coupling/Cohesion

Components 0
Dependencies 1

Importance

Changes 0
Metric Value
dl 32
loc 89
rs 10
c 0
b 0
f 0
wmc 4
lcom 0
cbo 1

4 Methods

Rating   Name   Duplication   Size   Complexity  
A test_register_autoloader() 0 20 1
A test_unregister_autoloader() 0 19 1
A test_load_class() 16 16 1
A test_load_class_does_nothing_without_class() 16 16 1

How to fix   Duplicated Code   

Duplicated Code

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 // phpcs:ignore WordPress.Files.FileName
2
/**
3
 * PHP autoloader test suite.
4
 *
5
 * @package automattic/jetpack-autoloader
6
 */
7
8
use Jetpack\AutoloaderTestData\Plugin\Test;
0 ignored issues
show
Bug introduced by
This use statement conflicts with another class in this namespace, Test.

Let’s assume that you have a directory layout like this:

.
|-- OtherDir
|   |-- Bar.php
|   `-- Foo.php
`-- SomeDir
    `-- Foo.php

and let’s assume the following content of Bar.php:

// Bar.php
namespace OtherDir;

use SomeDir\Foo; // This now conflicts the class OtherDir\Foo

If both files OtherDir/Foo.php and SomeDir/Foo.php are loaded in the same runtime, you will see a PHP error such as the following:

PHP Fatal error:  Cannot use SomeDir\Foo as Foo because the name is already in use in OtherDir/Foo.php

However, as OtherDir/Foo.php does not necessarily have to be loaded and the error is only triggered if it is loaded before OtherDir/Bar.php, this problem might go unnoticed for a while. In order to prevent this error from surfacing, you must import the namespace with a different alias:

// Bar.php
namespace OtherDir;

use SomeDir\Foo as SomeDirFoo; // There is no conflict anymore.
Loading history...
9
use PHPUnit\Framework\TestCase;
10
11
/**
12
 * Test suite class for the management of the PHP autoloader.
13
 *
14
 * @runTestsInSeparateProcesses Ensure that each test loads class files new.
15
 * @preserveGlobalState disabled
16
 */
17
class Test_PHP_Autoloader extends TestCase {
18
19
	/**
20
	 * Tests that the autoloader can be registered correctly.
21
	 */
22
	public function test_register_autoloader() {
23
		$removed_autoloader = 'Automattic\\Jetpack\\Autoloader\\jp123\\autoload';
24
		spl_autoload_register( $removed_autoloader );
25
26
		global $jetpack_autoloader_loader;
27
28
		$loader = $this->getMockBuilder( Version_Loader::class )
29
			->disableOriginalConstructor()
30
			->getMock();
31
32
		( new PHP_Autoloader() )->register_autoloader( $loader );
33
34
		$autoloaders = spl_autoload_functions();
35
36
		// Drop the autoloader so that PHPUnit does not throw errors.
37
		spl_autoload_unregister( PHP_Autoloader::class . '::load_class' );
38
39
		$this->assertContains( array( PHP_Autoloader::class, 'load_class' ), $autoloaders );
40
		$this->assertEquals( $loader, $jetpack_autoloader_loader );
41
	}
42
43
	/**
44
	 * Tests that the autoloader can be unregistered.
45
	 */
46
	public function test_unregister_autoloader() {
47
		// v2 Function Autoloader.
48
		$removed_autoloader = 'Automattic\\Jetpack\\Autoloader\\jp123\\autoload';
49
		spl_autoload_register( $removed_autoloader );
50
51
		( new PHP_Autoloader() )->unregister_autoloader();
52
53
		$autoloaders = spl_autoload_functions();
54
		$this->assertNotContains( $removed_autoloader, $autoloaders );
55
56
		// v2 Class Autoloader.
57
		$removed_autoloader = array( \Automattic\Jetpack\Autoloader\jp123\PHP_Autoloader::class, 'load_class' );
58
		spl_autoload_register( $removed_autoloader );
59
60
		( new PHP_Autoloader() )->unregister_autoloader();
61
62
		$autoloaders = spl_autoload_functions();
63
		$this->assertNotContains( $removed_autoloader, $autoloaders );
64
	}
65
66
	/**
67
	 * Tests that class files are loaded correctly.
68
	 */
69 View Code Duplication
	public function test_load_class() {
70
		$loader = $this->getMockBuilder( Version_Loader::class )
71
			->disableOriginalConstructor()
72
			->setMethods( array( 'find_class_file' ) )
73
			->getMock();
74
75
		global $jetpack_autoloader_loader;
76
		$jetpack_autoloader_loader = $loader;
77
		$loader->expects( $this->once() )
78
			->method( 'find_class_file' )
79
			->with( Test::class )
80
			->willReturn( TEST_DATA_PATH . '/plugins/dummy_current/includes/class-test.php' );
81
82
		$this->assertTrue( PHP_Autoloader::load_class( Test::class ) );
83
		$this->assertTrue( class_exists( Test::class, false ) );
84
	}
85
86
	/**
87
	 * Tests that nothing happens when a class file isn't found.
88
	 */
89 View Code Duplication
	public function test_load_class_does_nothing_without_class() {
90
		$loader = $this->getMockBuilder( Version_Loader::class )
91
			->disableOriginalConstructor()
92
			->setMethods( array( 'find_class_file' ) )
93
			->getMock();
94
95
		global $jetpack_autoloader_loader;
96
		$jetpack_autoloader_loader = $loader;
97
		$loader->expects( $this->once() )
98
			->method( 'find_class_file' )
99
			->with( Test::class )
100
			->willReturn( null );
101
102
		$this->assertFalse( PHP_Autoloader::load_class( Test::class ) );
103
		$this->assertFalse( class_exists( Test::class, false ) );
104
	}
105
}
106