Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding groups of paths #24

Merged
merged 13 commits into from
Oct 22, 2024
1 change: 1 addition & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ parameters:
inferPrivatePropertyTypeFromConstructor: true
reportUnmatchedIgnoredErrors: false
checkGenericClassInNonGenericObjectType: false
treatPhpDocTypesAsCertain: false

# Paths to be analyzed.
paths:
Expand Down
45 changes: 42 additions & 3 deletions src/Assets/Asset.php
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,21 @@ class Asset {
*/
protected string $root_path = '';

/**
* The path group name for this asset.
*
* A path group is a group of assets that share the same path which could be different that the root path or the asset's path.
*
* The order of priority goes like this:
*
* 1. If a specific root path is set, that will be used.
* 2. If a path group is set, that will be used.
* 3. Otherwise, the root path will be used.
*
* @var string
*/
protected string $group_path_name = '';

/**
* Content or callable that should be printed after the asset.
*
Expand Down Expand Up @@ -285,6 +300,19 @@ public function __construct( string $slug, string $file, string $version = null,
$this->infer_type();
}

/**
* Adds the asset to a group path.
*
* @since TBD
*
* @return static
*/
public function add_to_group_path( string $group_path_name ) {
$this->group_path_name = $group_path_name;

return $this;
}

/**
* Registers an asset.
*
Expand Down Expand Up @@ -630,7 +658,7 @@ public function clone_to( string $clone_type, ...$dependencies ) {
$slug,
str_replace( ".{$source_type}", ".{$clone_type}", $this->file ),
$this->version,
$this->root_path
$this->get_root_path()
);

$condition = $this->get_condition();
Expand Down Expand Up @@ -910,7 +938,8 @@ public function get_min_url(): string {
*/
public function get_path(): string {
if ( $this->path === null ) {
return Config::get_relative_asset_path();
$group_relative = $this->group_path_name ? Config::get_relative_path_of_group_path( $this->group_path_name ) : '';
return $group_relative ? $group_relative : Config::get_relative_asset_path();
}

return $this->path;
Expand All @@ -922,7 +951,17 @@ public function get_path(): string {
* @return ?string
*/
public function get_root_path(): ?string {
return $this->root_path;
if ( ! $this->group_path_name ) {
return $this->root_path;
}

if ( $this->root_path !== Config::get_path() ) {
return $this->root_path;
}

$group_path = Config::get_path_of_group_path( $this->group_path_name );

return $group_path ? $group_path : $this->root_path;
}

/**
Expand Down
102 changes: 82 additions & 20 deletions src/Assets/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,11 @@ class Config {
*/
protected static string $root_path = '';

/**
* @var array<string, array<string, string>>
*/
protected static array $group_paths = [];

/**
* @var string
*/
Expand All @@ -42,6 +47,55 @@ public static function get_hook_prefix(): string {
return static::$hook_prefix;
}

/**
* Gets the root path of a group.
*
* @since TBD
*
* @return string
*/
public static function get_path_of_group_path( string $group ): string {
return ( static::$group_paths[ $group ] ?? [] )['root'] ?? '';
}

/**
* Gets the relative path of a group.
*
* @since TBD
*
* @return string
*/
public static function get_relative_path_of_group_path( string $group ): string {
return ( static::$group_paths[ $group ] ?? [] )['relative'] ?? '';
}

/**
* Adds a group path.
*
* @since TBD
*
* @throws RuntimeException If the root or relative path is not specified.
*
* @param string $group_path_slug The slug of the group path.
* @param array<string, string> $paths The paths of the group path.
*
* @return void
*/
public static function add_group_path( string $group_path_slug, array $paths ): void {
if ( empty( $paths['root'] ) || ! is_string( $paths['root'] ) ) {
throw new RuntimeException( 'You must specify a root path for the group path.' );
}

if ( empty( $paths['relative'] ) || ! is_string( $paths['relative'] ) ) {
throw new RuntimeException( 'You must specify a relative path for the group path.' );
}

$paths['root'] = self::normalize_path( $paths['root'] );
$paths['relative'] = trailingslashit( $paths['relative'] );

static::$group_paths[ $group_path_slug ] = $paths;
}

/**
* Gets the root path of the project.
*
Expand Down Expand Up @@ -131,16 +185,35 @@ public static function set_relative_asset_path( string $path ) {
* @return void
*/
public static function set_path( string $path ) {
$plugin_dir = WP_PLUGIN_DIR;
static::$root_path = self::normalize_path( $path );
}

if ( DIRECTORY_SEPARATOR !== '/' ) {
$plugin_dir = str_replace( DIRECTORY_SEPARATOR, '/', $plugin_dir );
// Because the $path passed can be a constant like plugin_dir_path( __FILE__ ), we should check and replace the slash in the $path too.
$path = str_replace( DIRECTORY_SEPARATOR, '/', $path );
}
/**
* Sets the version of the project.
*
* @param string $version The version of the project.
*
* @return void
*/
public static function set_version( string $version ) {
static::$version = $version;
}

/**
* Normalizes a path.
*
* @since TBD
*
* @param string $path The path to normalize.
*
* @return string
*/
protected static function normalize_path( string $path ): string {
$plugin_dir = wp_normalize_path( WP_PLUGIN_DIR );
$path = wp_normalize_path( $path );

$plugins_content_dir_position = strpos( $path, $plugin_dir );
$themes_content_dir_position = strpos( $path, get_theme_root() );
$plugins_content_dir_position = $plugin_dir ? strpos( $path, $plugin_dir ) : false;
$themes_content_dir_position = strpos( $path, wp_normalize_path( get_theme_root() ) );

if (
$plugins_content_dir_position === false
Expand All @@ -154,17 +227,6 @@ public static function set_path( string $path ) {
$path = substr( $path, $themes_content_dir_position );
}

static::$root_path = trailingslashit( $path );
}

/**
* Sets the version of the project.
*
* @param string $version The version of the project.
*
* @return void
*/
public static function set_version( string $version ) {
static::$version = $version;
return trailingslashit( $path );
}
}
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
1 change: 1 addition & 0 deletions tests/_data/fake-feature/css/fake4.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array('some-dependency'), 'version' => '12345');
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
Empty file.
1 change: 1 addition & 0 deletions tests/_data/fake-feature/js/fake4.asset.php
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<?php return array('dependencies' => array('jquery'), 'version' => '12345');
Empty file.
Empty file.
Empty file.
54 changes: 50 additions & 4 deletions tests/wpunit/AssetsTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,47 @@ public function it_should_get_the_correct_url_when_wp_content_dir_and_wp_content
}
}

/**
* @test
*
* @dataProvider constantProvider
*/
public function it_should_get_the_correct_url_when_wp_content_dir_and_wp_content_url_are_diff_and_assets_are_in_asset_group( $id, $constants ) {
$slugs = [
'fake1' => [ true, false ],
'fake2' => [ false, false ],
'fake3' => [ true, true ]
];

foreach ( array_keys( $slugs ) as $slug ) {
Assets::init()->remove( $slug . '-script' );
Assets::init()->remove( $slug . '-style' );
}

foreach ( $constants as $constant => $value ) {
$this->set_const_value( $constant, $value );
$this->assertEquals( $value, constant( $constant ) );
}

Config::reset();

Config::set_hook_prefix( 'bork' );
Config::set_version( '1.1.0' );
Config::set_path( constant( 'WP_PLUGIN_DIR' ) . '/assets' );
Config::set_relative_asset_path( 'tests/_data/' );
Config::add_group_path( 'fake-group-path', [ 'root' => constant( 'WP_PLUGIN_DIR' ) . '/assets/tests', 'relative' => '_data/fake-feature'] );

foreach ( array_keys( $slugs ) as $slug ) {
Asset::add( $slug . '-script', $slug . '.js' )->add_to_group_path( 'fake-group-path' );
Asset::add( $slug . '-style', $slug . '.css' )->add_to_group_path( 'fake-group-path' );
}

foreach ( $slugs as $slug => $data ) {
$this->assert_minified_found( $slug, true, $data['0'], $data['1'], $id, 'fake-group-path', '/assets/tests/_data/fake-feature/' );
dpanta94 marked this conversation as resolved.
Show resolved Hide resolved
$this->assert_minified_found( $slug, false, $data['0'], $data['1'], $id, 'fake-group-path', '/assets/tests/_data/fake-feature/' );
}
}

public function constantProvider() {
$data = [
[
Expand Down Expand Up @@ -816,11 +857,14 @@ protected function existence_assertions( $test_slug_prefix ) {
* @param bool $is_js
* @param bool $has_min
* @param bool $has_only_min
* @param string $id
* @param string $add_to_path_group
* @param string $group_path_path
*/
protected function assert_minified_found( $slug_prefix, $is_js = true, $has_min = true, $has_only_min = false, $id = '' ) {
protected function assert_minified_found( $slug_prefix, $is_js = true, $has_min = true, $has_only_min = false, $id = '', $add_to_path_group = '', $group_path_path = '' ) {
$asset = Assets::init()->get( $slug_prefix . '-' . ( $is_js ? 'script' : 'style' ) );

$url = plugins_url( '/assets/tests/_data/' . ( $is_js ? 'js' : 'css' ) . '/' . $slug_prefix );
$url = plugins_url( ( $group_path_path ? $group_path_path : '/assets/tests/_data/' ) . ( $is_js ? 'js' : 'css' ) . '/' . $slug_prefix );

$urls = [];

Expand Down Expand Up @@ -865,9 +909,11 @@ static function ( $url ) {

// Remove and re add to clear cache.
Assets::init()->remove( $slug_prefix . '-' . ( $is_js ? 'script' : 'style' ) );
Asset::add( $slug_prefix . '-' . ( $is_js ? 'script' : 'style' ), $slug_prefix . '.' . ( $is_js ? 'js' : 'css' ) )->register();
$asset = Asset::add( $slug_prefix . '-' . ( $is_js ? 'script' : 'style' ), $slug_prefix . '.' . ( $is_js ? 'js' : 'css' ) );

$asset = Assets::init()->get( $slug_prefix . '-' . ( $is_js ? 'script' : 'style' ) );
if ( $add_to_path_group ) {
$asset->add_to_group_path( $add_to_path_group );
}

$this->assertEquals(
$urls['1'],
Expand Down
39 changes: 39 additions & 0 deletions tests/wpunit/ConfigTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,4 +75,43 @@ public function should_reset() {
$this->assertInstanceOf( \RuntimeException::class, $e );
}
}

/**
* @test
*/
public function should_add_group_paths() {
Config::add_group_path( 'my-group-path-1', [ 'root' => dirname( dirname( __DIR__ ) ) . '/src/feature-1', 'relative' => 'app-1' ] );
dpanta94 marked this conversation as resolved.
Show resolved Hide resolved
Config::add_group_path( 'my-group-path-2', [ 'root' => dirname( dirname( __DIR__ ) ) . '/src/feature-2', 'relative' => 'app-2' ] );

$this->assertEquals( WP_PLUGIN_DIR . '/assets/src/feature-1/', Config::get_path_of_group_path( 'my-group-path-1' ) );
$this->assertEquals( 'app-1/', Config::get_relative_path_of_group_path( 'my-group-path-1' ) );
$this->assertEquals( WP_PLUGIN_DIR . '/assets/src/feature-2/', Config::get_path_of_group_path( 'my-group-path-2' ) );
$this->assertEquals( 'app-2/', Config::get_relative_path_of_group_path( 'my-group-path-2' ) );
}

/**
* @test
*/
public function should_throw_exception_when_root_is_not_provided() {
$this->expectException( \RuntimeException::class );
$this->expectExceptionMessage( 'You must specify a root path for the group path.' );
Config::add_group_path( 'my-group-path-1', [ 'relative' => 'app-1' ] );
}

/**
* @test
*/
public function should_throw_exception_when_relative_is_not_provided() {
$this->expectException( \RuntimeException::class );
$this->expectExceptionMessage( 'You must specify a relative path for the group path.' );
Config::add_group_path( 'my-group-path-1', [ 'root' => 'app-1' ] );
}

/**
* @test
*/
public function should_return_empty_string_if_no_group() {
$this->assertEquals( '', Config::get_path_of_group_path( 'test1-' . wp_rand( 1, 9999 ) ) );
$this->assertEquals( '', Config::get_relative_path_of_group_path( 'test2-' . wp_rand( 1, 9999 ) ) );
}
}
Loading