-
Notifications
You must be signed in to change notification settings - Fork 1k
Expand file tree
/
Copy pathframework.feature
More file actions
575 lines (502 loc) · 16.7 KB
/
framework.feature
File metadata and controls
575 lines (502 loc) · 16.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
Feature: Load WP-CLI
Scenario: A plugin calling wp_signon() shouldn't fatal
Given a WP installation
And I run `wp user create testuser test@example.org --user_pass=testuser`
And a wp-content/mu-plugins/test.php file:
"""
<?php
add_action( 'plugins_loaded', function(){
wp_signon( array( 'user_login' => 'testuser', 'user_password' => 'testuser' ) );
});
"""
When I run `wp option get home`
Then STDOUT should not be empty
Scenario: A command loaded before WordPress then calls WordPress to load
Given a WP installation
And a custom-cmd.php file:
"""
<?php
class Load_WordPress_Command_Class extends WP_CLI_Command {
/**
* @when before_wp_load
*/
public function __invoke() {
if ( ! function_exists( 'update_option' ) ) {
WP_CLI::log( 'WordPress not loaded.' );
}
WP_CLI::get_runner()->load_wordpress();
if ( function_exists( 'update_option' ) ) {
WP_CLI::log( 'WordPress loaded!' );
}
WP_CLI::get_runner()->load_wordpress();
WP_CLI::log( 'load_wordpress() can safely be called twice.' );
}
}
WP_CLI::add_command( 'load-wordpress', 'Load_WordPress_Command_Class' );
"""
When I run `wp --require=custom-cmd.php load-wordpress`
Then STDOUT should be:
"""
WordPress not loaded.
WordPress loaded!
load_wordpress() can safely be called twice.
"""
Scenario: A command loaded before WordPress then calls WordPress to load, but WP doesn't exist
Given an empty directory
And a custom-cmd.php file:
"""
<?php
class Load_WordPress_Command_Class extends WP_CLI_Command {
/**
* @when before_wp_load
*/
public function __invoke() {
if ( ! function_exists( 'update_option' ) ) {
WP_CLI::log( 'WordPress not loaded.' );
}
WP_CLI::get_runner()->load_wordpress();
if ( function_exists( 'update_option' ) ) {
WP_CLI::log( 'WordPress loaded!' );
}
WP_CLI::get_runner()->load_wordpress();
WP_CLI::log( 'load_wordpress() can safely be called twice.' );
}
}
WP_CLI::add_command( 'load-wordpress', 'Load_WordPress_Command_Class' );
"""
When I try `wp --require=custom-cmd.php load-wordpress`
Then STDOUT should be:
"""
WordPress not loaded.
"""
And STDERR should contain:
"""
Error: This does not seem to be a WordPress installation.
"""
# `wp db create` does not yet work on SQLite,
# See https://github.com/wp-cli/db-command/issues/234
@require-mysql
Scenario: Globalize global variables in wp-config.php
Given an empty directory
And WP files
And a wp-config-extra.php file:
"""
$redis_server = 'foo';
"""
When I run `wp config create {CORE_CONFIG_SETTINGS} --skip-check --extra-php < wp-config-extra.php`
Then the wp-config.php file should contain:
"""
$redis_server = 'foo';
"""
When I run `wp db create`
And I run `wp core install --url='localhost:8001' --title='Test' --admin_user=wpcli --admin_email=admin@example.com --admin_password=1`
Then STDOUT should not be empty
When I run `wp eval 'echo $GLOBALS["redis_server"];'`
Then STDOUT should be:
"""
foo
"""
Scenario: Use a custom error code with WP_CLI::error()
Given an empty directory
And a exit-normal.php file:
"""
<?php
WP_CLI::error( 'This is return code 1.' );
"""
And a exit-higher.php file:
"""
<?php
WP_CLI::error( 'This is return code 5.', 5 );
"""
And a no-exit.php file:
"""
<?php
WP_CLI::error( 'This has no exit.', false );
WP_CLI::error( 'So I can use multiple lines.', false );
"""
When I try `wp --require=exit-normal.php`
Then the return code should be 1
And STDERR should be:
"""
Error: This is return code 1.
"""
When I try `wp --require=exit-higher.php`
Then the return code should be 5
And STDERR should be:
"""
Error: This is return code 5.
"""
When I try `wp --require=no-exit.php`
Then the return code should be 0
And STDERR should be:
"""
Error: This has no exit.
Error: So I can use multiple lines.
"""
Scenario: Debug flag shows backtrace on error
Given an empty directory
And a debug-error.php file:
"""
<?php
function my_custom_function() {
WP_CLI::error( 'Test error message.' );
}
my_custom_function();
"""
When I try `wp --require=debug-error.php --debug`
Then the return code should be 1
And STDERR should contain:
"""
Error: Test error message.
"""
And STDERR should contain:
"""
Script called exit from:
"""
And STDERR should contain:
"""
debug-error.php:
"""
And STDERR should contain:
"""
Backtrace:
"""
Scenario: Debug flag shows backtrace on halt
Given an empty directory
And a debug-halt.php file:
"""
<?php
function trigger_halt() {
WP_CLI::halt( 2 );
}
trigger_halt();
"""
When I try `wp --require=debug-halt.php --debug`
Then the return code should be 2
And STDERR should contain:
"""
Script called exit from:
"""
And STDERR should contain:
"""
debug-halt.php:
"""
And STDERR should contain:
"""
Backtrace:
"""
Scenario: Without debug flag, no backtrace is shown
Given an empty directory
And a no-debug-error.php file:
"""
<?php
WP_CLI::error( 'Simple error.' );
"""
When I try `wp --require=no-debug-error.php`
Then the return code should be 1
And STDERR should be:
"""
Error: Simple error.
"""
Scenario: A plugin calling wp_redirect() shouldn't redirect
Given a WP installation
And a wp-content/mu-plugins/redirect.php file:
"""
<?php
add_action( 'init', function(){
wp_redirect( 'http://apple.com' );
});
"""
When I try `wp option get home`
Then STDERR should contain:
"""
Warning: Some code is trying to do a URL redirect.
"""
Scenario: A plugin calling wp_redirect() shouldn't redirect in admin context
Given a WP installation
And a wp-content/mu-plugins/redirect.php file:
"""
<?php
add_action( 'init', function(){
wp_redirect( 'http://apple.com' );
});
"""
When I try `wp plugin list --debug=bootstrap`
Then STDERR should contain:
"""
Debug: Some code is trying to do a URL redirect.
"""
Scenario: It should be possible to work on a site in maintenance mode
Given a WP installation
And a .maintenance file:
"""
<?php
$upgrading = time();
"""
When I run `wp option get home`
Then STDOUT should be:
"""
https://example.com
"""
@require-mysql
Scenario: Handle error when WordPress cannot connect to the database host
Given a WP installation
And a invalid-host.php file:
"""
<?php
error_reporting( error_reporting() & ~E_NOTICE );
define( 'DB_HOST', 'localghost' );
"""
When I try `wp --require=invalid-host.php option get home`
Then STDERR should contain:
"""
Error: Error establishing a database connection.
"""
When I try `wp --require=invalid-host.php option get home`
Then STDERR should contain:
"""
Error: Error establishing a database connection.
"""
Scenario: Allow WP_CLI hooks to pass arguments to callbacks
Given an empty directory
And a my-command.php file:
"""
<?php
WP_CLI::add_hook( 'foo', function( $bar ){
WP_CLI::log( $bar );
});
WP_CLI::add_command( 'my-command', function( $args ){
WP_CLI::do_hook( 'foo', $args[0] );
}, array( 'when' => 'before_wp_load' ) );
"""
When I run `wp --require=my-command.php my-command bar`
Then STDOUT should be:
"""
bar
"""
And STDERR should be empty
Scenario: WP-CLI sets $table_prefix appropriately on multisite
Given a WP multisite installation
And I run `wp site create --slug=first`
When I run `wp eval 'global $table_prefix; echo $table_prefix;'`
Then STDOUT should be:
"""
wp_
"""
When I run `wp eval 'global $blog_id; echo $blog_id;'`
Then STDOUT should be:
"""
1
"""
When I run `wp --url=example.com/first eval 'global $table_prefix; echo $table_prefix;'`
Then STDOUT should be:
"""
wp_2_
"""
When I run `wp --url=example.com/first eval 'global $blog_id; echo $blog_id;'`
Then STDOUT should be:
"""
2
"""
Scenario: Use --assume-https to preserve HTTPS scheme in URL functions
Given a WP multisite installation
And I run `wp option update siteurl https://example.com`
And I run `wp site option update siteurl https://example.com`
And I run `wp site option update home https://example.com`
When I run `wp option get siteurl`
Then STDOUT should be:
"""
https://example.com
"""
When I run `wp --assume-https site list --field=url`
Then STDOUT should be:
"""
https://example.com/
"""
When I run `wp --assume-https eval "echo site_url();"`
Then STDOUT should be:
"""
https://example.com
"""
When I run `wp --assume-https eval "echo home_url();"`
Then STDOUT should be:
"""
https://example.com
"""
When I run `wp --assume-https eval "echo network_site_url();"`
Then STDOUT should be:
"""
https://example.com/
"""
When I run `wp --assume-https eval "echo network_home_url();"`
Then STDOUT should be:
"""
https://example.com/
"""
# `wp db reset` does not yet work on SQLite,
# See https://github.com/wp-cli/db-command/issues/234
@require-mysql
Scenario: Show error message when site isn't found and there aren't additional prefixes.
Given a WP installation
And I run `wp db reset --yes`
When I try `wp option get home`
Then STDERR should be:
"""
Error: The site you have requested is not installed.
Run `wp core install` to create database tables.
"""
And STDOUT should be empty
@skip-object-cache
Scenario: Show potential table prefixes when site isn't found, single site.
Given a WP installation
And "$table_prefix = 'wp_';" replaced with "$table_prefix = 'cli_';" in the wp-config.php file
When I try `wp option get home`
Then STDERR should be:
"""
Error: The site you have requested is not installed.
Your table prefix is 'cli_'. Found installation with table prefix: wp_.
Or, run `wp core install` to create database tables.
"""
And STDOUT should be empty
# Use try to cater for wp-db errors in old WPs.
When I try `wp core install --url=example.com --title=example --admin_user=wpcli --admin_email=wpcli@example.com`
Then STDOUT should contain:
"""
Success:
"""
And the return code should be 0
Given "$table_prefix = 'cli_';" replaced with "$table_prefix = 'test_';" in the wp-config.php file
When I try `wp option get home`
Then STDERR should be:
"""
Error: The site you have requested is not installed.
Your table prefix is 'test_'. Found installations with table prefix: cli_, wp_.
Or, run `wp core install` to create database tables.
"""
And STDOUT should be empty
# `wp db query` does not yet work on SQLite,
# See https://github.com/wp-cli/db-command/issues/234
@require-mysql
Scenario: Display a more helpful error message when site can't be found
Given a WP multisite installation
And "define( 'DOMAIN_CURRENT_SITE', 'example.com' );" replaced with "define( 'DOMAIN_CURRENT_SITE', 'example.org' );" in the wp-config.php file
When I try `wp option get home`
Then STDERR should be:
"""
Error: Site 'example.org/' not found. Verify DOMAIN_CURRENT_SITE matches an existing site or use `--url=<url>` to override.
"""
When I try `wp option get home --url=example.io`
Then STDERR should be:
"""
Error: Site 'example.io' not found. Verify `--url=<url>` matches an existing site.
"""
Given "define( 'DOMAIN_CURRENT_SITE', 'example.org' );" replaced with " " in the wp-config.php file
# WP < 5.0 have bug which will not find a blog given an empty domain unless wp_blogs.domain empty which was (partly) addressed by https://core.trac.wordpress.org/ticket/42299
# So empty wp_blogs.domain to make behavior consistent across WP versions.
And I run `wp db query 'UPDATE wp_blogs SET domain = NULL'`
When I run `cat wp-config.php`
Then STDOUT should not contain:
"""
DOMAIN_CURRENT_SITE
"""
# This will work as finds blog with empty domain and thus uses `home` option.
# Expect a warning from WP core for PHP 8+.
When I try `wp option get home`
Then STDOUT should be:
"""
https://example.com
"""
# Undo above.
Given I run `wp db query 'UPDATE wp_blogs SET domain = "example.com"'`
When I try `wp option get home --url=example.io`
Then STDERR should be:
"""
Error: Site 'example.io' not found. Verify `--url=<url>` matches an existing site.
"""
# `wp db query` does not yet work on SQLite,
# See https://github.com/wp-cli/db-command/issues/234
@require-mysql
Scenario: Show detailed error when multisite network is not found
Given a WP multisite installation
And a force-network-not-found.php file:
"""
<?php
// Force ms_not_installed() to be triggered by returning empty network
WP_CLI::add_wp_hook(
'the_networks',
static function() {
return [];
}
);
"""
And I run `wp config delete DOMAIN_CURRENT_SITE --type=constant`
# This should trigger ms_not_installed() which now shows detailed error
# because we set current_screen to make is_admin() return true
When I try `wp --require=force-network-not-found.php option get home`
Then STDERR should contain:
"""
Error establishing a database connection.
"""
And STDERR should contain:
"""
If your site does not display, please contact the owner of this network.
"""
# `wp db query` does not yet work on SQLite,
# See https://github.com/wp-cli/db-command/issues/234
@require-mysql
Scenario: Show detailed error when hitting ms_network_not_found
Given a WP multisite installation
And a force-network-not-found.php file:
"""
<?php
// Force ms_not_installed() to be triggered by returning empty network
WP_CLI::add_wp_hook(
'the_networks',
static function() {
return [
new \WP_Network( new stdClass() ),
new \WP_Network( new stdClass() ),
];
}
);
"""
And I run `wp config delete DOMAIN_CURRENT_SITE --type=constant`
# This should trigger ms_not_installed() which now shows detailed error
# because we set current_screen to make is_admin() return true
When I try `wp --require=force-network-not-found.php option get home`
Then STDERR should contain:
"""
Error: Network not found. Verify the network exists in the database or run `wp core multisite-install`.
"""
Scenario: Don't show 'sitecategories' table unless global terms are enabled
Given a WP multisite installation
When I run `wp db tables`
Then STDOUT should not contain:
"""
wp_sitecategories
"""
When I run `wp db tables --network`
Then STDOUT should not contain:
"""
wp_sitecategories
"""
Scenario: WP-CLI autoloaders take precedence over plugin autoloaders after WordPress loads
Given a WP installation
And a wp-content/mu-plugins/prepend-autoloader.php file:
"""
<?php
// Simulate a plugin that prepends its own autoloader.
function wpcli_test_mu_autoload( $class ) {
// This intentionally does nothing but exists to be prepended.
}
spl_autoload_register(
'wpcli_test_mu_autoload',
true,
true
);
"""
When I run `wp eval '$autoloaders = spl_autoload_functions(); $first = $autoloaders[0]; $plugin_index = array_search( "wpcli_test_mu_autoload", $autoloaders, true ); echo ( $plugin_index !== false && 0 !== $plugin_index ) ? "WP-CLI autoloader is first" : "Plugin autoloader is first";'`
Then STDOUT should contain:
"""
WP-CLI autoloader is first
"""