Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Implement functions to parse modules with their data from modules dir…
…ectory and include tests including demo test data.
  • Loading branch information
felixarntz committed Dec 2, 2021
commit 08960ac321da5ecdf09a11700363d3b211152a53
125 changes: 103 additions & 22 deletions admin/load.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,33 +182,114 @@ function perflab_get_focus_areas() {
* Gets all available modules.
*
* This function iterates through the modules directory and therefore should only be called on the modules page.
* It parses each module's data, similar to how plugin data is parsed in WordPress core.
* It searches all modules, similar to how plugins are searched in the WordPress core function `get_plugins()`.
*
* @since 1.0.0
*
* @param string $modules_root Modules root directory to look for modules in. Default is the `/modules` directory
* in the plugin's root.
* @return array Associative array of parsed module data, keyed by module slug. Fields for every module include
* 'name', 'description', 'focus', and 'experimental'.
*/
function perflab_get_modules() {
// TODO: Implement dynamic module data parsing. Depends on https://github.com/WordPress/performance/issues/2.
return array(
'demo-module-1' => array(
'name' => 'Demo Module 1',
'description' => 'This is the description for demo module 1.',
'focus' => 'javascript',
'experimental' => false,
),
'demo-module-2' => array(
'name' => 'Demo Module 2',
'description' => 'This is the description for demo module 2.',
'focus' => 'something',
'experimental' => true,
),
'demo-module-3' => array(
'name' => 'Demo Module 3',
'description' => 'This is the description for demo module 3.',
'focus' => 'images',
'experimental' => false,
),
function perflab_get_modules( $modules_root = null ) {
if ( null === $modules_root ) {
$modules_root = dirname( __DIR__ ) . '/modules';
}

$modules = array();
$module_files = array();
$modules_dir = @opendir( $modules_root );

if ( $modules_dir ) {
// phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
while ( ( $file = readdir( $modules_dir ) ) !== false ) {
if ( '.' === substr( $file, 0, 1 ) ) {
continue;
}

// Unlike plugins, modules must be in a directory.
if ( ! is_dir( $modules_root . '/' . $file ) ) {
continue;
}

$module_dir = @opendir( $modules_root . '/' . $file );
if ( $module_dir ) {
// phpcs:ignore WordPress.CodeAnalysis.AssignmentInCondition.FoundInWhileCondition
while ( ( $subfile = readdir( $module_dir ) ) !== false ) {
if ( '.' === substr( $subfile, 0, 1 ) ) {
continue;
}

// Unlike plugins, module main files must be called `load.php`.
if ( 'load.php' !== $subfile ) {
continue;
}

$module_files[] = "$file/$subfile";
}

closedir( $module_dir );
}
}

closedir( $modules_dir );
}

foreach ( $module_files as $module_file ) {
if ( ! is_readable( "$modules_root/$module_file" ) ) {
continue;
}

$module_data = perflab_get_module_data( "$modules_root/$module_file" );
if ( ! $module_data ) {
continue;
}

$modules[ dirname( $module_file ) ] = $module_data;
}

uasort(
$modules,
function( $a, $b ) {
return strnatcasecmp( $a['name'], $b['name'] );
}
);

return $modules;
}

/**
* Parses the module main file to get the module's metadata.
*
* This is similar to how plugin data is parsed in the WordPress core function `get_plugin_data()`.
*
* @since 1.0.0
*
* @param string $module_file Absolute path to the main module file.
* @return array|bool Associative array of parsed module data, or false on failure. Fields for every module include
* 'name', 'description', 'focus', and 'experimental'.
*/
function perflab_get_module_data( $module_file ) {
$default_headers = array(
'name' => 'Module Name',
'description' => 'Description',
'focus' => 'Focus',
'experimental' => 'Experimental',
);

$module_data = get_file_data( $module_file, $default_headers, 'perflab_module' );

// Module name and description are the minimum requirements.
if ( ! $module_data['name'] || ! $module_data['description'] ) {
return false;
}

// Experimental should be a boolean.
if ( 'yes' === strtolower( trim( $module_data['experimental'] ) ) ) {
$module_data['experimental'] = true;
} else {
$module_data['experimental'] = false;
}

return $module_data;
}
14 changes: 14 additions & 0 deletions tests/admin/load-tests.php
Original file line number Diff line number Diff line change
Expand Up @@ -173,4 +173,18 @@ public function test_perflab_get_focus_areas() {
);
$this->assertSame( $expected_focus_areas, array_keys( perflab_get_focus_areas() ) );
}

public function test_perflab_get_modules() {
// Use test data directory with demo modules that match the modules declared on top of this file.
$modules = perflab_get_modules( TESTS_PLUGIN_DIR . '/tests/testdata/modules' );
$this->assertSame( self::$demo_modules, $modules );
}

public function test_perflab_get_module_data() {
// Use test data directory with demo modules that match the modules declared on top of this file.
foreach ( self::$demo_modules as $module_slug => $expected_module_data ) {
$module_data = perflab_get_module_data( TESTS_PLUGIN_DIR . '/tests/testdata/modules/' . $module_slug . '/load.php' );
$this->assertSame( $expected_module_data, $module_data );
}
}
}
11 changes: 11 additions & 0 deletions tests/testdata/modules/demo-module-1/load.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Module Name: Demo Module 1
* Description: This is the description for demo module 1.
* Focus: javascript
* Experimental: No
*
* @package performance-lab
*/

// This is a demo module and does nothing.
11 changes: 11 additions & 0 deletions tests/testdata/modules/demo-module-2/load.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Module Name: Demo Module 2
* Description: This is the description for demo module 2.
* Focus: something
* Experimental: Yes
*
* @package performance-lab
*/

// This is a demo module and does nothing.
11 changes: 11 additions & 0 deletions tests/testdata/modules/demo-module-3/load.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php
/**
* Module Name: Demo Module 3
* Description: This is the description for demo module 3.
* Focus: images
* Experimental: No
*
* @package performance-lab
*/

// This is a demo module and does nothing.