|
1
|
|
|
<?php |
|
2
|
|
|
/** |
|
3
|
|
|
* This file is part of mundschenk-at/check-wp-requirements. |
|
4
|
|
|
* |
|
5
|
|
|
* Copyright 2017-2018 Peter Putzer. |
|
6
|
|
|
* |
|
7
|
|
|
* This program is free software; you can redistribute it and/or |
|
8
|
|
|
* modify it under the terms of the GNU General Public License |
|
9
|
|
|
* as published by the Free Software Foundation; either version 2 |
|
10
|
|
|
* of the License, or ( at your option ) any later version. |
|
11
|
|
|
* |
|
12
|
|
|
* This program is distributed in the hope that it will be useful, |
|
13
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
14
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
15
|
|
|
* GNU General Public License for more details. |
|
16
|
|
|
* |
|
17
|
|
|
* You should have received a copy of the GNU General Public License |
|
18
|
|
|
* along with this program; if not, write to the Free Software |
|
19
|
|
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
20
|
|
|
* |
|
21
|
|
|
* @package mundschenk-at/check-wp-requirements/tests |
|
22
|
|
|
* @license http://www.gnu.org/licenses/gpl-2.0.html |
|
23
|
|
|
*/ |
|
24
|
|
|
|
|
25
|
|
|
namespace Mundschenk\Check_WordPress_Requirements\Tests; |
|
26
|
|
|
|
|
27
|
|
|
use Brain\Monkey\Actions; |
|
28
|
|
|
use Brain\Monkey\Filters; |
|
29
|
|
|
use Brain\Monkey\Functions; |
|
30
|
|
|
|
|
31
|
|
|
use org\bovigo\vfs\vfsStream; |
|
32
|
|
|
|
|
33
|
|
|
use Mockery as m; |
|
34
|
|
|
|
|
35
|
|
|
/** |
|
36
|
|
|
* Mundschenk_WP_Requirements unit test. |
|
37
|
|
|
* |
|
38
|
|
|
* @coversDefaultClass \Mundschenk_WP_Requirements |
|
39
|
|
|
* @usesDefaultClass \Mundschenk_WP_Requirements |
|
40
|
|
|
* |
|
41
|
|
|
* @uses Mundschenk_WP_Requirements::__construct |
|
42
|
|
|
*/ |
|
43
|
|
|
class Mundschenk_WP_Requirements_Test extends TestCase { |
|
44
|
|
|
|
|
45
|
|
|
/** |
|
46
|
|
|
* Test fixture. |
|
47
|
|
|
* |
|
48
|
|
|
* @var \Mundschenk_WP_Requirements |
|
49
|
|
|
*/ |
|
50
|
|
|
protected $req; |
|
51
|
|
|
|
|
52
|
|
|
/** |
|
53
|
|
|
* Sets up the fixture, for example, opens a network connection. |
|
54
|
|
|
* This method is called before a test is executed. |
|
55
|
|
|
*/ |
|
56
|
|
|
protected function setUp() { // @codingStandardsIgnoreLine |
|
57
|
|
|
|
|
58
|
|
|
// Set up virtual filesystem. |
|
59
|
|
|
vfsStream::setup( 'root', null, [ |
|
60
|
|
|
'plugin' => [ |
|
61
|
|
|
'partials' => [ |
|
62
|
|
|
'requirements-error-notice.php' => 'REQUIREMENTS_ERROR', |
|
63
|
|
|
], |
|
64
|
|
|
], |
|
65
|
|
|
] ); |
|
66
|
|
|
set_include_path( 'vfs://root/' ); // @codingStandardsIgnoreLine |
|
67
|
|
|
|
|
68
|
|
|
Functions\expect( 'wp_parse_args' )->once()->andReturnUsing( function( $array, $defaults ) { |
|
69
|
|
|
return \array_merge( $defaults, $array ); |
|
70
|
|
|
} ); |
|
71
|
|
|
|
|
72
|
|
|
$this->req = m::mock( \Mundschenk_WP_Requirements::class, [ |
|
73
|
|
|
'Foobar', |
|
74
|
|
|
'plugin/plugin.php', |
|
75
|
|
|
'textdomain', |
|
76
|
|
|
[ |
|
77
|
|
|
'php' => '5.6.0', |
|
78
|
|
|
'multibyte' => true, |
|
79
|
|
|
'utf-8' => true, |
|
80
|
|
|
], |
|
81
|
|
|
] )->shouldAllowMockingProtectedMethods()->makePartial(); |
|
82
|
|
|
|
|
83
|
|
|
parent::setUp(); |
|
84
|
|
|
} |
|
85
|
|
|
|
|
86
|
|
|
/** |
|
87
|
|
|
* Necesssary clean-up work. |
|
88
|
|
|
*/ |
|
89
|
|
|
protected function tearDown() { // @codingStandardsIgnoreLine |
|
90
|
|
|
parent::tearDown(); |
|
91
|
|
|
} |
|
92
|
|
|
|
|
93
|
|
|
|
|
94
|
|
|
|
|
95
|
|
|
/** |
|
96
|
|
|
* Test constructor. |
|
97
|
|
|
* |
|
98
|
|
|
* @covers ::__construct |
|
99
|
|
|
*/ |
|
100
|
|
|
public function test_constructor() { |
|
101
|
|
|
Functions\expect( 'wp_parse_args' )->once()->andReturnUsing( function( $array, $defaults ) { |
|
102
|
|
|
return \array_merge( $defaults, $array ); |
|
103
|
|
|
} ); |
|
104
|
|
|
|
|
105
|
|
|
$req = m::mock( \Mundschenk_WP_Requirements::class, [ 'Foobar', 'plugin/plugin.php', 'textdomain', [ 'php' => '5.3.5' ] ] ); |
|
106
|
|
|
|
|
107
|
|
|
$this->assertAttributeSame( 'plugin/plugin.php', 'plugin_file', $req ); |
|
108
|
|
|
$this->assertAttributeSame( 'Foobar', 'plugin_name', $req ); |
|
109
|
|
|
$this->assertAttributeSame( 'textdomain', 'textdomain', $req ); |
|
110
|
|
|
|
|
111
|
|
|
$requirements = $this->getValue( $req, 'install_requirements', \Mundschenk_WP_Requirements::class ); |
|
112
|
|
|
$this->assertArrayHasKey( 'php', $requirements ); |
|
113
|
|
|
$this->assertArrayHasKey( 'multibyte', $requirements ); |
|
114
|
|
|
$this->assertArrayHasKey( 'utf-8', $requirements ); |
|
115
|
|
|
|
|
116
|
|
|
$this->assertEquals( '5.3.5', $requirements['php'] ); |
|
117
|
|
|
$this->assertFalse( $requirements['multibyte'] ); |
|
118
|
|
|
$this->assertFalse( $requirements['utf-8'] ); |
|
119
|
|
|
} |
|
120
|
|
|
|
|
121
|
|
|
/** |
|
122
|
|
|
* Test display_error_notice. |
|
123
|
|
|
* |
|
124
|
|
|
* @covers ::display_error_notice |
|
125
|
|
|
*/ |
|
126
|
|
|
public function test_display_error_notice() { |
|
127
|
|
|
$this->expectOutputString( 'REQUIREMENTS_ERROR' ); |
|
128
|
|
|
|
|
129
|
|
|
$this->invokeMethod( $this->req, 'display_error_notice', [ 'foo' ] ); |
|
130
|
|
|
} |
|
131
|
|
|
|
|
132
|
|
|
/** |
|
133
|
|
|
* Test display_error_notice. |
|
134
|
|
|
* |
|
135
|
|
|
* @covers ::display_error_notice |
|
136
|
|
|
* |
|
137
|
|
|
* @expectedExceptionMessage Too few arguments to function |
|
138
|
|
|
*/ |
|
139
|
|
|
public function test_display_error_notice_no_arguments() { |
|
140
|
|
|
$this->expectOutputString( '' ); |
|
141
|
|
|
|
|
142
|
|
|
// PHP < 7.0 raises an error instead of throwing an "exception". |
|
143
|
|
|
if ( version_compare( phpversion(), '7.0.0', '<' ) ) { |
|
144
|
|
|
$this->expectException( \PHPUnit_Framework_Error::class ); |
|
145
|
|
|
} elseif ( version_compare( phpversion(), '7.1.0', '<' ) ) { |
|
146
|
|
|
$this->expectException( \PHPUnit\Framework\Error\Warning::class ); |
|
147
|
|
|
} else { |
|
148
|
|
|
$this->expectException( \ArgumentCountError::class ); |
|
149
|
|
|
} |
|
150
|
|
|
|
|
151
|
|
|
$this->invokeMethod( $this->req, 'display_error_notice', [] ); |
|
152
|
|
|
} |
|
153
|
|
|
|
|
154
|
|
|
/** |
|
155
|
|
|
* Test display_error_notice. |
|
156
|
|
|
* |
|
157
|
|
|
* @covers ::display_error_notice |
|
158
|
|
|
*/ |
|
159
|
|
|
public function test_display_error_notice_empty_format() { |
|
160
|
|
|
$this->expectOutputString( '' ); |
|
161
|
|
|
|
|
162
|
|
|
$this->invokeMethod( $this->req, 'display_error_notice', [ '' ] ); |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
/** |
|
166
|
|
|
* Test admin_notices_php_version_incompatible. |
|
167
|
|
|
* |
|
168
|
|
|
* @covers ::admin_notices_php_version_incompatible |
|
169
|
|
|
*/ |
|
170
|
|
|
public function test_admin_notices_php_version_incompatible() { |
|
171
|
|
|
Functions\expect( '__' )->with( m::type( 'string' ), 'textdomain' )->atLeast()->once()->andReturn( 'translated' ); |
|
|
|
|
|
|
172
|
|
|
$this->req->shouldReceive( 'display_error_notice' )->once(); |
|
|
|
|
|
|
173
|
|
|
|
|
174
|
|
|
$this->assertNull( $this->req->admin_notices_php_version_incompatible() ); |
|
175
|
|
|
} |
|
176
|
|
|
|
|
177
|
|
|
/** |
|
178
|
|
|
* Test admin_notices_mbstring_incompatible. |
|
179
|
|
|
* |
|
180
|
|
|
* @covers ::admin_notices_mbstring_incompatible |
|
181
|
|
|
*/ |
|
182
|
|
|
public function test_admin_notices_mbstring_incompatible() { |
|
183
|
|
|
Functions\expect( '__' )->with( m::type( 'string' ), 'textdomain' )->atLeast()->once()->andReturn( 'translated' ); |
|
|
|
|
|
|
184
|
|
|
$this->req->shouldReceive( 'display_error_notice' )->once(); |
|
|
|
|
|
|
185
|
|
|
|
|
186
|
|
|
$this->assertNull( $this->req->admin_notices_mbstring_incompatible() ); |
|
187
|
|
|
} |
|
188
|
|
|
|
|
189
|
|
|
/** |
|
190
|
|
|
* Test admin_notices_charset_incompatible. |
|
191
|
|
|
* |
|
192
|
|
|
* @covers ::admin_notices_charset_incompatible |
|
193
|
|
|
*/ |
|
194
|
|
|
public function test_admin_notices_charset_incompatible() { |
|
195
|
|
|
Functions\expect( '__' )->with( m::type( 'string' ), 'textdomain' )->atLeast()->once()->andReturn( 'translated' ); |
|
|
|
|
|
|
196
|
|
|
Functions\expect( 'get_bloginfo' )->with( 'charset' )->once()->andReturn( '8859-1' ); |
|
197
|
|
|
$this->req->shouldReceive( 'display_error_notice' )->once(); |
|
|
|
|
|
|
198
|
|
|
|
|
199
|
|
|
$this->assertNull( $this->req->admin_notices_charset_incompatible() ); |
|
200
|
|
|
} |
|
201
|
|
|
|
|
202
|
|
|
/** |
|
203
|
|
|
* Provides data for testing check_utf8_support. |
|
204
|
|
|
* |
|
205
|
|
|
* @return array |
|
206
|
|
|
*/ |
|
207
|
|
|
public function provide_check_utf8_support_data() { |
|
208
|
|
|
return [ |
|
209
|
|
|
[ 'utf-8', true ], |
|
210
|
|
|
[ 'UTF-8', true ], |
|
211
|
|
|
[ '8859-1', false ], |
|
212
|
|
|
[ 'foobar', false ], |
|
213
|
|
|
]; |
|
214
|
|
|
} |
|
215
|
|
|
|
|
216
|
|
|
/** |
|
217
|
|
|
* Test check_utf8_support. |
|
218
|
|
|
* |
|
219
|
|
|
* @covers ::check_utf8_support |
|
220
|
|
|
* |
|
221
|
|
|
* @dataProvider provide_check_utf8_support_data |
|
222
|
|
|
* |
|
223
|
|
|
* @param string $charset The blog charset. |
|
224
|
|
|
* @param bool $expected The expected result. |
|
225
|
|
|
*/ |
|
226
|
|
|
public function test_check_utf8_support( $charset, $expected ) { |
|
227
|
|
|
Functions\expect( 'get_bloginfo' )->with( 'charset' )->once()->andReturn( $charset ); |
|
228
|
|
|
|
|
229
|
|
|
$this->assertSame( $expected, $this->invokeMethod( $this->req, 'check_utf8_support' ) ); |
|
230
|
|
|
} |
|
231
|
|
|
|
|
232
|
|
|
/** |
|
233
|
|
|
* Test check_utf8_support. |
|
234
|
|
|
* |
|
235
|
|
|
* @covers ::check_multibyte_support |
|
236
|
|
|
*/ |
|
237
|
|
|
public function test_check_multibyte_support() { |
|
238
|
|
|
// This will be true because mbstring is a requirement for running the test suite. |
|
239
|
|
|
$this->assertTrue( $this->invokeMethod( $this->req, 'check_multibyte_support' ) ); |
|
240
|
|
|
} |
|
241
|
|
|
|
|
242
|
|
|
/** |
|
243
|
|
|
* Provides data for testing check. |
|
244
|
|
|
* |
|
245
|
|
|
* @return array |
|
246
|
|
|
*/ |
|
247
|
|
|
public function provide_check_data() { |
|
248
|
|
|
return [ |
|
249
|
|
|
[ true, true, true, true, true ], |
|
250
|
|
|
[ false, false, false, true, false ], |
|
251
|
|
|
[ true, false, false, true, false ], |
|
252
|
|
|
[ false, true, false, true, false ], |
|
253
|
|
|
[ false, false, true, true, false ], |
|
254
|
|
|
[ true, true, true, false, true ], |
|
255
|
|
|
[ false, false, false, false, false ], |
|
256
|
|
|
[ true, false, false, false, false ], |
|
257
|
|
|
[ false, true, false, false, false ], |
|
258
|
|
|
[ false, false, true, false, false ], |
|
259
|
|
|
[ true, true, false, true, false ], |
|
260
|
|
|
]; |
|
261
|
|
|
} |
|
262
|
|
|
|
|
263
|
|
|
/** |
|
264
|
|
|
* Test check. |
|
265
|
|
|
* |
|
266
|
|
|
* @covers ::check |
|
267
|
|
|
* |
|
268
|
|
|
* @dataProvider provide_check_data |
|
269
|
|
|
* |
|
270
|
|
|
* @param bool $php_version PHP version check flag. |
|
271
|
|
|
* @param bool $multibyte Multibyte support check flag. |
|
272
|
|
|
* @param bool $charset Charset check flag. |
|
273
|
|
|
* @param bool $admin Result of is_admin(). |
|
274
|
|
|
* @param bool $expected Expected result. |
|
275
|
|
|
*/ |
|
276
|
|
|
public function test_check( $php_version, $multibyte, $charset, $admin, $expected ) { |
|
277
|
|
|
Functions\expect( 'is_admin' )->zeroOrMoreTimes()->andReturn( $admin ); |
|
278
|
|
|
|
|
279
|
|
|
// Fake PHP version check. |
|
280
|
|
|
if ( ! $php_version ) { |
|
281
|
|
|
$this->setValue( $this->req, 'install_requirements', [ |
|
282
|
|
|
'php' => '999.0.0', |
|
283
|
|
|
'multibyte' => true, |
|
284
|
|
|
'utf-8' => true, |
|
285
|
|
|
], \Mundschenk_WP_Requirements::class ); |
|
286
|
|
|
} |
|
287
|
|
|
|
|
288
|
|
|
$this->req->shouldReceive( 'check_multibyte_support' )->times( (int) $php_version )->andReturn( $multibyte ); |
|
|
|
|
|
|
289
|
|
|
$this->req->shouldReceive( 'check_utf8_support' )->times( (int) ( $php_version && $multibyte ) )->andReturn( $charset ); |
|
|
|
|
|
|
290
|
|
|
|
|
291
|
|
|
if ( $admin ) { |
|
292
|
|
|
$php_times = $php_version ? 0 : 1; |
|
293
|
|
|
$multibyte_times = ! $php_version || $multibyte ? 0 : 1; |
|
294
|
|
|
$charset_times = ! $php_version || ! $multibyte || $charset ? 0 : 1; |
|
295
|
|
|
|
|
296
|
|
|
if ( ! $expected ) { |
|
297
|
|
|
Functions\expect( 'load_plugin_textdomain' )->once()->with( 'textdomain' ); |
|
298
|
|
|
} |
|
299
|
|
|
|
|
300
|
|
|
Actions\expectAdded( 'admin_notices' )->with( [ $this->req, 'admin_notices_php_version_incompatible' ] )->times( $php_times ); |
|
301
|
|
|
Actions\expectAdded( 'admin_notices' )->with( [ $this->req, 'admin_notices_mbstring_incompatible' ] )->times( $multibyte_times ); |
|
302
|
|
|
Actions\expectAdded( 'admin_notices' )->with( [ $this->req, 'admin_notices_charset_incompatible' ] )->times( $charset_times ); |
|
303
|
|
|
} |
|
304
|
|
|
|
|
305
|
|
|
$this->assertSame( $expected, $this->invokeMethod( $this->req, 'check' ) ); |
|
306
|
|
|
} |
|
307
|
|
|
|
|
308
|
|
|
/** |
|
309
|
|
|
* Test deactivate_plugin. |
|
310
|
|
|
* |
|
311
|
|
|
* @covers ::deactivate_plugin |
|
312
|
|
|
*/ |
|
313
|
|
|
public function test_deactivate_plugin() { |
|
314
|
|
|
Functions\expect( 'plugin_basename' )->with( 'plugin/plugin.php' )->once()->andReturn( 'plugin' ); |
|
315
|
|
|
Functions\expect( 'deactivate_plugins' )->with( 'plugin' )->once(); |
|
316
|
|
|
|
|
317
|
|
|
$this->assertNull( $this->req->deactivate_plugin() ); |
|
318
|
|
|
} |
|
319
|
|
|
} |
|
320
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignorePhpDoc annotation to the duplicate definition and it will be ignored.