Options
The runtime provides in-memory implementations of get_option() and get_site_option(). They do not use a database.
Configure options
Set initial values before or after boot:
use Unitest_WP_Copy\WP_Options;
use Unitest_WP_Copy\WP_Runtime;
WP_Options::set( 'home', 'https://example.test' );
WP_Options::set( 'siteurl', 'https://example.test' );
WP_Options::set_site( 'registration', 'all' );
WP_Runtime::boot();
WP_Options::set( 'my_plugin_title', 'Test title' );Bootstrap keeps provided values and adds any missing defaults.
How option lookup works
Options should be reed via regular WP functions:
get_option( 'options_name' );
get_site_option( 'options_name' );get_option()
get_option() resolves a value in this order:
pre_option_{$option}andpre_optionfilters.WP_Optionsstore value, followed by theoption_{$option}filter.WP_Mockhandler, if the option is absent from the store.default_option_{$option}filter and the supplied default value.
INFO
A pre-option filter short-circuits the remaining lookup when it returns a value other than false.
get_site_option()
The same lookup order, using the network-option equivalents:
pre_site_option_{$option}andpre_site_optionfilters.WP_Optionsstore value, followed by thesite_option_{$option}filter.WP_Mockhandler, if the option is absent from the store.default_site_option_{$option}filter and the supplied default value.
Outside multisite, get_site_option() delegates to get_option().
Store & Restore option state
Isolate test state. Save and restore both stores with an internal LIFO stack:
protected function setUp(): void {
parent::setUp();
WP_Options::save_state();
}
protected function tearDown(): void {
WP_Options::restore_state();
parent::tearDown();
}
public function test__plugin_title(): void {
WP_Options::set( 'my_plugin_title', 'Test title' );
self::assertSame( 'Test title', get_option( 'my_plugin_title' ) );
}save_state() and restore_state() require a booted runtime. An unmatched restore_state() throws LogicException.
State does not include constants, hooks, $_SERVER, or other WP globals.
Nested state saves
WP_Options::save_state(); // State A.
WP_Options::set( 'blogname', 'B' );
WP_Options::save_state(); // State B.
WP_Options::set( 'blogname', 'C' );
WP_Options::restore_state(); // Restores B.
WP_Options::restore_state(); // Restores A.Default options
The authoritative default lists live in WP_Options. They cover the deterministic values required by copied runtime functions.
For regular site:
[
'home' => 'https://wp.test',
'siteurl' => 'https://wp.test',
'gmt_offset' => 0,
'timezone_string' => 'UTC',
'start_of_week' => 1,
'language' => 'en-US',
'blogname' => 'Unitest WP Copy',
'blogdescription' => 'unitest-wp-copy runtime',
'blog_public' => '1',
'admin_email' => 'admin@wp.test',
'stylesheet' => 'wp-test-stylesheet',
'template' => 'wp-test-template',
'use_smilies' => true,
'use_balanceTags' => true,
'permalink_structure' => '/%postname%/',
'show_on_front' => 'posts',
'page_on_front' => 0,
'page_for_posts' => 0,
'site_icon' => 0,
'WPLANG' => '',
'blog_charset' => 'UTF-8',
'html_type' => 'text/html',
'thumbnail_size_w' => 150,
'thumbnail_size_h' => 150,
'thumbnail_crop' => true,
'medium_size_w' => 300,
'medium_size_h' => 300,
'medium_crop' => false,
'medium_large_size_w' => 768,
'medium_large_size_h' => 0,
'medium_large_crop' => false,
'large_size_w' => 1024,
'large_size_h' => 1024,
'large_crop' => false,
'banned_email_domains' => [],
'upload_filetypes' => 'jpg jpeg png gif',
'upload_space_check_disabled' => false,
'fileupload_maxk' => 1500,
'registration' => 'none',
'blog_upload_space' => 100,
'https_migration_required' => false,
]For network:
[
'siteurl' => 'https://wp.test',
'WPLANG' => '',
'banned_email_domains' => [],
'upload_filetypes' => 'jpg jpeg png gif',
'upload_space_check_disabled' => false,
'fileupload_maxk' => 1500,
'registration' => 'none',
'blog_upload_space' => 100,
]