Completed
Push — add/cli ( 74cf7f...2842da )
by
unknown
10:13
created

Test_Autoloader::test_load_class()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 16

Duplication

Lines 16
Ratio 100 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 16
loc 16
rs 9.7333
c 0
b 0
f 0
1
<?php // phpcs:ignore WordPress.Files.FileName
2
/**
3
 * 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 Autoloader.
13
 *
14
 * @runTestsInSeparateProcesses Ensure that each test loads class files new.
15
 * @preserveGlobalState disabled
16
 */
17
class Test_Autoloader extends TestCase {
18
19
	/**
20
	 * The version loader mock.
21
	 *
22
	 * @var Version_Loader|\PHPUnit\Framework\MockObject\MockObject
23
	 */
24
	private $version_loader;
25
26
	/**
27
	 * Setup runs before each test.
28
	 *
29
	 * @before
30
	 */
31
	public function set_up() {
32
		$this->version_loader = $this->getMockBuilder( Version_Loader::class )
33
			->disableOriginalConstructor()
34
			->setMethods( array( 'load_filemap' ) )
35
			->getMock();
36
	}
37
38
	/**
39
	 * Tests that the autoloader is initialized correctly and registers the correct hook.
40
	 */
41
	public function test_init_autoloader() {
42
		global $test_container;
43
44
		$plugin_locator = $this->getMockBuilder( Plugin_Locator::class )
45
			->disableOriginalConstructor()
46
			->getMock();
47
		$test_container->replace( Plugin_Locator::class, $plugin_locator );
48
49
		$plugins_handler = $this->getMockBuilder( Plugins_Handler::class )
50
			->disableOriginalConstructor()
51
			->getMock();
52
		$test_container->replace( Plugins_Handler::class, $plugins_handler );
53
54
		$guard = $this->getMockBuilder( Latest_Autoloader_Guard::class )
55
			->disableOriginalConstructor()
56
			->getMock();
57
		$test_container->replace( Latest_Autoloader_Guard::class, $guard );
58
59
		$autoloader_handler = $this->getMockBuilder( Autoloader_Handler::class )
60
			->disableOriginalConstructor()
61
			->getMock();
62
		$test_container->replace( Autoloader_Handler::class, $autoloader_handler );
63
64
		$plugin_locator->expects( $this->once() )
65
			->method( 'find_current_plugin' )
66
			->willReturn( TEST_DATA_PATH . '/plugins/dummy_current' );
67
		$plugins_handler->expects( $this->once() )
68
			->method( 'get_cached_plugins' )
69
			->willReturn( array( TEST_DATA_PATH . '/plugins/dummy_newer' ) );
70
		$plugins_handler->expects( $this->once() )
71
			->method( 'get_active_plugins' )
72
			->willReturn( array( TEST_DATA_PATH . '/plugins/dummy_current' ) );
73
		$guard->expects( $this->once() )
74
			->method( 'should_stop_init' )
75
			->with(
76
				TEST_DATA_PATH . '/plugins/dummy_current',
77
				array( TEST_DATA_PATH . '/plugins/dummy_current', TEST_DATA_PATH . '/plugins/dummy_newer' )
78
			)
79
			->willReturn( false );
80
		$autoloader_handler->expects( $this->once() )
81
			->method( 'create_autoloader' )
82
			->with( array( TEST_DATA_PATH . '/plugins/dummy_current', TEST_DATA_PATH . '/plugins/dummy_newer' ) );
83
84
		Autoloader::init( $test_container );
85
	}
86
87
	/**
88
	 * Tests that the autoloader is stopped by the guard correctly.
89
	 */
90
	public function test_init_autoloader_stopped_by_guard() {
91
		global $test_container;
92
93
		$plugin_locator = $this->getMockBuilder( Plugin_Locator::class )
94
			->disableOriginalConstructor()
95
			->getMock();
96
		$test_container->replace( Plugin_Locator::class, $plugin_locator );
97
98
		$plugins_handler = $this->getMockBuilder( Plugins_Handler::class )
99
			->disableOriginalConstructor()
100
			->getMock();
101
		$test_container->replace( Plugins_Handler::class, $plugins_handler );
102
103
		$guard = $this->getMockBuilder( Latest_Autoloader_Guard::class )
104
			->disableOriginalConstructor()
105
			->getMock();
106
		$test_container->replace( Latest_Autoloader_Guard::class, $guard );
107
108
		$plugin_locator->expects( $this->once() )
109
			->method( 'find_current_plugin' )
110
			->willReturn( TEST_DATA_PATH . '/plugins/dummy_current' );
111
		$plugins_handler->expects( $this->once() )
112
			->method( 'get_cached_plugins' )
113
			->willReturn( array( TEST_DATA_PATH . '/plugins/dummy_newer' ) );
114
		$plugins_handler->expects( $this->once() )
115
			->method( 'get_active_plugins' )
116
			->willReturn( array( TEST_DATA_PATH . '/plugins/dummy_current' ) );
117
		$guard->expects( $this->once() )
118
			->method( 'should_stop_init' )
119
			->with(
120
				TEST_DATA_PATH . '/plugins/dummy_current',
121
				array( TEST_DATA_PATH . '/plugins/dummy_current', TEST_DATA_PATH . '/plugins/dummy_newer' )
122
			)
123
			->willReturn( true );
124
125
		Autoloader::init( $test_container );
126
	}
127
128
	/**
129
	 * Tests that activate registers the autoloader.
130
	 */
131
	public function test_activate_registers_autoloader() {
132
		global $jetpack_autoloader_loader;
133
134
		$this->version_loader->expects( $this->once() )->method( 'load_filemap' );
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Version_Loader>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
135
136
		Autoloader::activate( $this->version_loader );
137
138
		$autoloaders = spl_autoload_functions();
139
		$this->assertEquals( array( Autoloader::class, 'load_class' ), reset( $autoloaders ) );
140
		$this->assertEquals( $this->version_loader, $jetpack_autoloader_loader );
141
	}
142
143
	/**
144
	 * Tests that activate removes the v2 autoload functions.
145
	 */
146 View Code Duplication
	public function test_activate_removes_v2_autoload_functions() {
147
		$removed_autoloader = 'Automattic\\Jetpack\\Autoloader\\jp123\\autoload';
148
		spl_autoload_register( $removed_autoloader );
149
150
		$this->version_loader->expects( $this->once() )->method( 'load_filemap' );
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Version_Loader>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
151
152
		Autoloader::activate( $this->version_loader );
153
154
		$autoloaders = spl_autoload_functions();
155
		$this->assertEquals( array( Autoloader::class, 'load_class' ), reset( $autoloaders ) );
156
		$this->assertNotContains( $removed_autoloader, $autoloaders );
157
	}
158
159
	/**
160
	 * Tests that activate removes the v2 autoload class.
161
	 */
162 View Code Duplication
	public function test_activate_removes_v2_class_autoloader() {
163
		$removed_autoloader = \Automattic\Jetpack\Autoloader\jp123\Autoloader::class . '::load_class';
164
		spl_autoload_register( $removed_autoloader );
165
166
		$this->version_loader->expects( $this->once() )->method( 'load_filemap' );
0 ignored issues
show
Bug introduced by
The method expects() does not seem to exist on object<Version_Loader>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
167
168
		Autoloader::activate( $this->version_loader );
169
170
		$autoloaders = spl_autoload_functions();
171
		$this->assertEquals( array( Autoloader::class, 'load_class' ), reset( $autoloaders ) );
172
		$this->assertNotContains( $removed_autoloader, $autoloaders );
173
	}
174
175
	/**
176
	 * Tests that class files are loaded correctly.
177
	 */
178 View Code Duplication
	public function test_load_class() {
179
		$loader = $this->getMockBuilder( Version_Loader::class )
180
			->disableOriginalConstructor()
181
			->setMethods( array( 'find_class_file' ) )
182
			->getMock();
183
184
		global $jetpack_autoloader_loader;
185
		$jetpack_autoloader_loader = $loader;
186
		$loader->expects( $this->once() )
187
			->method( 'find_class_file' )
188
			->with( Test::class )
189
			->willReturn( TEST_DATA_PATH . '/plugins/dummy_current/includes/class-test.php' );
190
191
		$this->assertTrue( Autoloader::load_class( Test::class ) );
192
		$this->assertTrue( class_exists( Test::class, false ) );
193
	}
194
195
	/**
196
	 * Tests that nothing happens when a class file isn't found.
197
	 */
198 View Code Duplication
	public function test_load_class_does_nothing_without_class() {
199
		$loader = $this->getMockBuilder( Version_Loader::class )
200
			->disableOriginalConstructor()
201
			->setMethods( array( 'find_class_file' ) )
202
			->getMock();
203
204
		global $jetpack_autoloader_loader;
205
		$jetpack_autoloader_loader = $loader;
206
		$loader->expects( $this->once() )
207
			->method( 'find_class_file' )
208
			->with( Test::class )
209
			->willReturn( null );
210
211
		$this->assertFalse( Autoloader::load_class( Test::class ) );
212
		$this->assertFalse( class_exists( Test::class, false ) );
213
	}
214
}
215