Skip to content

Commit 8d03809

Browse files
authored
fix: split test running for integrations (plugins) (#2904)
While testing integrations (ACF, etc.), all the tests were run with plugins active which lead to some inconsistencies. Tests are split to run separately and avoid those issues. An important change was also made on meta return type. Timber uses the same return signature than WordPress, e.g. returning an empty string when the field is empty instead of evaluating it through `empty()`.
1 parent 7e00eeb commit 8d03809

16 files changed

+136
-263
lines changed

.github/workflows/php-unit-tests.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -139,17 +139,16 @@ jobs:
139139
- name: Install tests
140140
run: bash bin/install-wp-tests.sh wordpress_test root '' 127.0.0.1:${{ job.services.mysql.ports['3306'] }} ${{ matrix.wp }} true
141141

142-
143142
- name: Run tests
144143
if: ${{ !matrix.webp }}
145-
run: composer run test:no-cov
144+
run: composer run test
146145
env:
147146
WP_MULTISITE: ${{ matrix.multisite }}
148147

149148
- name: Run tests with coverage
150149
if: matrix.coverage == true
151150
run: |
152-
composer run test:codecov
151+
composer run test:integration:codecov
153152
154153
- name: Upload coverage results to Coveralls
155154
if: matrix.coverage == true

bin/install-wp-tests.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ SKIP_DB_CREATE=${6-false}
1414

1515
TMPDIR=${TMPDIR-/tmp}
1616
TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
17-
TMPDIR=$(realpath $TMPDIR)
17+
# TMPDIR=$(realpath $TMPDIR)
1818
WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
1919
WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress}
2020

composer.json

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -120,9 +120,17 @@
120120
"@test",
121121
"@cs"
122122
],
123-
"test": "phpunit",
124-
"test:codecov": "phpunit --coverage-clover ./build/logs/clover.xml",
125-
"test:make-pot": "wp i18n make-pot src tests/languages/timber.pot --domain= && wp i18n make-pot ./tests/assets/translations ./tests/languages/timber-test.pot --domain=timber-test",
126-
"test:no-cov": "phpunit --no-coverage"
123+
"test": [
124+
"@test:integration:acf",
125+
"@test:integration:coauthors-plus",
126+
"@test:integration:wpml",
127+
"@test:integration"
128+
],
129+
"test:integration": "phpunit --no-coverage --exclude-group acf,coauthors-plus,wpml",
130+
"test:integration:acf": "phpunit --no-coverage --group acf",
131+
"test:integration:coauthors-plus": "phpunit --no-coverage --group coauthors-plus",
132+
"test:integration:codecov": "phpunit --coverage-clover ./build/logs/clover.xml",
133+
"test:integration:wpml": "phpunit --no-coverage --group wpml",
134+
"test:make-pot": "wp i18n make-pot src tests/languages/timber.pot --domain= && wp i18n make-pot ./tests/assets/translations ./tests/languages/timber-test.pot --domain=timber-test"
127135
}
128136
}

src/CoreEntity.php

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ protected function fetch_meta($field_name = '', $args = [], $apply_filters = tru
177177
$object_meta = \get_metadata($object_type, $this->ID, $field_name, true);
178178

179179
// Mimick $single argument when fetching all meta values.
180-
if (empty($field_name) && \is_array($object_meta) && !empty($object_meta)) {
180+
if (empty($field_name) && \is_array($object_meta)) {
181181
$object_meta = \array_map(function ($meta) {
182182
/**
183183
* We use array_key_exists() instead of isset(), because when the meta value is null, isset() would
@@ -192,11 +192,6 @@ protected function fetch_meta($field_name = '', $args = [], $apply_filters = tru
192192
return $meta;
193193
}, $object_meta);
194194
}
195-
196-
// Empty result.
197-
if (empty($object_meta)) {
198-
$object_meta = empty($field_name) ? [] : null;
199-
}
200195
}
201196

202197
if ($apply_filters) {

tests/bootstrap.php

Lines changed: 51 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,35 +14,66 @@
1414
// Get access to tests_add_filter() function.
1515
require_once $_tests_dir . '/includes/functions.php';
1616

17-
/**
18-
* Callback to manually load the plugin
19-
*/
20-
function _manually_load_plugin()
17+
function tt_get_arg(string $key)
2118
{
22-
Timber\Timber::init();
19+
foreach ($_SERVER['argv'] as $index => $arg) {
20+
if ($key === substr($arg, 0, strlen($key))) {
21+
return [
22+
'index' => $index,
23+
$key => str_replace("{$key}=", '', $arg),
24+
];
25+
}
26+
}
27+
return false;
28+
}
29+
30+
function tt_is_group(string $group_name)
31+
{
32+
$group = tt_get_arg('--group');
33+
if (false === $group) {
34+
return false;
35+
}
36+
37+
$group_name_index = ++$group['index'];
2338

24-
require dirname(__FILE__) . '/../wp-content/plugins/advanced-custom-fields/acf.php';
25-
if (file_exists(dirname(__FILE__) . '/../wp-content/plugins/co-authors-plus/co-authors-plus.php')) {
26-
include dirname(__FILE__) . '/../wp-content/plugins/co-authors-plus/co-authors-plus.php';
39+
if (!isset($_SERVER['argv'][$group_name_index])) {
40+
return false;
2741
}
42+
43+
return ($group_name === $_SERVER['argv'][$group_name_index]);
2844
}
2945

3046
// Add plugin to active mu-plugins to make sure it gets loaded.
31-
tests_add_filter('muplugins_loaded', '_manually_load_plugin');
47+
tests_add_filter('muplugins_loaded', function () {
48+
// Load Timber
49+
Timber\Timber::init();
3250

33-
// WPML integration
34-
define('ICL_LANGUAGE_CODE', 'en');
51+
if (tt_is_group('acf')) {
52+
require __DIR__ . '/../wp-content/plugins/advanced-custom-fields/acf.php';
53+
}
3554

36-
/**
37-
* Mocked function for testing menus in WPML
38-
*/
39-
function wpml_object_id_filter($element_id, $element_type = 'post', $return_original_if_missing = false, $language_code = null)
40-
{
41-
$locations = get_nav_menu_locations();
42-
if (isset($locations['extra-menu'])) {
43-
return $locations['extra-menu'];
55+
if (tt_is_group('coauthors-plus')) {
56+
require __DIR__ . '/../wp-content/plugins/co-authors-plus/co-authors-plus.php';
57+
}
58+
59+
if (tt_is_group('wpml')) {
60+
// WPML integration
61+
define('ICL_LANGUAGE_CODE', 'en');
62+
}
63+
});
64+
65+
if (tt_is_group('wpml')) {
66+
/**
67+
* Mocked function for testing menus in WPML
68+
*/
69+
function wpml_object_id_filter($element_id, $element_type = 'post', $return_original_if_missing = false, $language_code = null)
70+
{
71+
$locations = get_nav_menu_locations();
72+
if (isset($locations['extra-menu'])) {
73+
return $locations['extra-menu'];
74+
}
75+
return $element_id;
4476
}
45-
return $element_id;
4677
}
4778

4879
/**

tests/test-timber-cache.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ public function testTimberLoaderCacheObject()
329329
$clear = $loader->clear_cache_timber(Timber\Loader::CACHE_OBJECT);
330330
$this->assertTrue($clear);
331331
$works = true;
332-
332+
333333
if (isset($wp_object_cache->cache[Timber\Loader::CACHEGROUP])
334334
&& !empty($wp_object_cache->cache[Timber\Loader::CACHEGROUP])) {
335335
$works = false;

tests/test-timber-image-resize.php

Lines changed: 0 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -180,56 +180,4 @@ public function testSideloadedResize()
180180

181181
$this->assertEquals($expected, $sideloaded);
182182
}
183-
184-
public function testWPMLurlRemote()
185-
{
186-
// this test replicates the url issue caused by the WPML language identifier in the url
187-
// However, WPML can't be installed with composer so this test mocks the WPML plugin
188-
189-
// define ICL_LANGUAGE_CODE constant because on subsequent calls (i.e. if downloaded file exists),
190-
// replacement done in Integrations/WPML.php will fail and trigger an error here
191-
if (!defined('ICL_LANGUAGE_CODE')) {
192-
define('ICL_LANGUAGE_CODE', 'en');
193-
}
194-
195-
// WPML uses a filter to alter the home_url
196-
$home_url_filter = function ($url) {
197-
return $url . '/en';
198-
};
199-
add_filter('home_url', $home_url_filter, -10, 4);
200-
201-
$img = 'https://raw.githubusercontent.com/timber/timber/master/tests/assets/arch-2night.jpg';
202-
// test with a local and external file
203-
$resized = Timber\ImageHelper::resize($img, 50, 50);
204-
205-
// make sure the base url has not been duplicated (https://github.com/timber/timber/issues/405)
206-
$this->assertLessThanOrEqual(1, substr_count($resized, 'example.org'));
207-
// make sure the image has been resized
208-
$resized = Timber\URLHelper::url_to_file_system($resized);
209-
$this->assertTrue(TestTimberImage::checkSize($resized, 50, 50), 'image should be resized');
210-
}
211-
212-
public function testWPMLurlLocal()
213-
{
214-
// this test replicates the url issue caused by the WPML language identifier in the url
215-
// However, WPML can't be installed with composer so this test mocks the WPML plugin
216-
217-
// WPML uses a filter to alter the home_url
218-
$home_url_filter = function ($url) {
219-
return $url . '/en';
220-
};
221-
add_filter('home_url', $home_url_filter, -10, 4);
222-
223-
// test with a local and external file
224-
$img = 'arch.jpg';
225-
$img = TestTimberImage::copyTestAttachment($img);
226-
227-
$resized = Timber\ImageHelper::resize($img, 50, 50);
228-
229-
// make sure the base url has not been duplicated (https://github.com/timber/timber/issues/405)
230-
$this->assertLessThanOrEqual(1, substr_count($resized, 'example.org'));
231-
// make sure the image has been resized
232-
$resized = Timber\URLHelper::url_to_file_system($resized);
233-
$this->assertTrue(TestTimberImage::checkSize($resized, 50, 50), 'image should be resized');
234-
}
235183
}

tests/test-timber-integration-acf.php

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,22 @@
33
use Timber\User;
44

55
/**
6+
* @group acf
67
* @group users-api
78
* @group comments-api
89
* @group integrations
910
* @group posts-api
1011
*/
1112
class TestTimberIntegrationACF extends Timber_UnitTestCase
1213
{
14+
public function setUp(): void
15+
{
16+
if (!function_exists('get_field')) {
17+
$this->markTestSkipped('ACF plugin is not loaded');
18+
}
19+
parent::setUp();
20+
}
21+
1322
public function testACFGetFieldPost()
1423
{
1524
$post_id = $this->factory->post->create();
@@ -462,6 +471,38 @@ public function testACFObjectTransformsDoesNotTriggerNotice()
462471
$this->assertSame(false, $file);
463472
}
464473

474+
/**
475+
* @ticket #824
476+
*/
477+
public function testTermWithNativeMetaNotExisting()
478+
{
479+
$tid = $this->factory->term->create([
480+
'name' => 'News',
481+
'taxonomy' => 'category',
482+
]);
483+
484+
add_term_meta($tid, 'bar', 'qux');
485+
;
486+
$wp_native_value = get_term_meta($tid, 'foo', true);
487+
$acf_native_value = get_field('foo', 'category_' . $tid);
488+
489+
$valid_wp_native_value = get_term_meta($tid, 'bar', true);
490+
$valid_acf_native_value = get_field('bar', 'category_' . $tid);
491+
492+
$term = Timber::get_term($tid);
493+
494+
//test baseline "bar" data
495+
$this->assertEquals('qux', $valid_wp_native_value);
496+
$this->assertEquals('qux', $valid_acf_native_value);
497+
$this->assertEquals('qux', $term->bar);
498+
499+
//test the one that doesn't exist
500+
$this->assertEquals('string', gettype($wp_native_value));
501+
$this->assertEmpty($wp_native_value);
502+
$this->assertNull($acf_native_value);
503+
$this->assertNotTrue($term->meta('foo'));
504+
}
505+
465506
private function register_field($field_name, $field_type, $field_args = [])
466507
{
467508
$group_key = sprintf('group_%s', uniqid());

tests/test-timber-integration-wpml.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,14 @@
66
*/
77
class TestTimberIntegrationWPML extends Timber_UnitTestCase
88
{
9+
public function setUp(): void
10+
{
11+
if (!defined('ICL_LANGUAGE_CODE')) {
12+
$this->markTestSkipped('WPML plugin is not loaded');
13+
}
14+
parent::setUp();
15+
}
16+
917
public function testFileSystemToURLWithWPML()
1018
{
1119
$this->add_filter_temporarily('home_url', function ($url, $path) {

tests/test-timber-integrations-coauthors.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
/**
66
* @group posts-api
77
* @group integrations
8+
* @group coauthors-plus
89
*/
910
class TestTimberIntegrationsCoAuthors extends Timber_UnitTestCase
1011
{
@@ -20,12 +21,12 @@ public function expectedDeprecated()
2021
parent::expectedDeprecated();
2122
}
2223

23-
public function set_up()
24+
public function setUp(): void
2425
{
2526
if (!class_exists('CoAuthors_Plus')) {
26-
return $this->markTestSkipped('CoAuthors_Plus plugin not loaded');
27+
$this->markTestSkipped('CoAuthors Plus plugin is not loaded');
2728
}
28-
parent::set_up();
29+
parent::setUp();
2930
}
3031

3132
/* ----------------

0 commit comments

Comments
 (0)