Add shortcut methods for the LegacyProxy in the WooCommerce class.

The following methods are added and can be invoked using `WC()`,
they just redirect to the same methods in LegacyProxy:

call_function
call_static
get_instance_of
This commit is contained in:
Nestor Soriano 2020-07-16 12:01:50 +02:00
parent abf53086ca
commit 6fd84a0401
3 changed files with 282 additions and 0 deletions

View File

@ -8,6 +8,8 @@
defined( 'ABSPATH' ) || exit;
use Automattic\WooCommerce\Proxies\LegacyProxy;
/**
* Main WooCommerce Class.
*
@ -902,4 +904,51 @@ final class WooCommerce {
public function is_wc_admin_active() {
return function_exists( 'wc_admin_url' );
}
/**
* Call a user function. This should be used to execute any non-idempotent function, especially
* those in the `includes` directory or provided by WordPress.
*
* @param string $function_name The function to execute.
* @param mixed ...$parameters The parameters to pass to the function.
*
* @return mixed The result from the function.
*
* @since 4.4
*/
public function call_function( $function_name, ...$parameters ) {
return wc_get_container()->get( LegacyProxy::class )->call_function( $function_name, ...$parameters );
}
/**
* Call a static method in a class. This should be used to execute any non-idempotent method in classes
* from the `includes` directory.
*
* @param string $class_name The name of the class containing the method.
* @param string $method_name The name of the method.
* @param mixed ...$parameters The parameters to pass to the method.
*
* @return mixed The result from the method.
*
* @since 4.4
*/
public function call_static( $class_name, $method_name, ...$parameters ) {
return wc_get_container()->get( LegacyProxy::class )->call_static( $class_name, $method_name, ...$parameters );
}
/**
* Gets an instance of a given legacy class.
* This must not be used to get instances of classes in the `src` directory.
*
* @param string $class_name The name of the class to get an instance for.
* @param mixed ...$args Parameters to be passed to the class constructor or to the appropriate internal 'get_instance_of_' method.
*
* @return object The instance of the class.
* @throws \Exception The requested class belongs to the `src` directory, or there was an error creating an instance of the class.
*
* @since 4.4
*/
public function get_instance_of( string $class_name, ...$args ) {
return wc_get_container()->get( LegacyProxy::class )->get_instance_of( $class_name, ...$args );
}
}

View File

@ -0,0 +1,128 @@
<?php
/**
* ClassThatDependsOnLegacyCodeTest class file
*
* @package Automattic\WooCommerce\Tests\Proxies
*/
namespace Automattic\WooCommerce\Tests\Proxies;
use Automattic\WooCommerce\Proxies\LegacyProxy;
use Automattic\WooCommerce\Tests\Proxies\ExampleClasses\ClassThatDependsOnLegacyCode;
use Automattic\WooCommerce\Tests\Internal\DependencyManagement\ExampleClasses\DependencyClass;
/**
* Tests for a class that depends on legacy code
*/
class ClassThatDependsOnLegacyCodeTest extends \WC_Unit_Test_Case {
/**
* The system under test.
*
* @var LegacyProxy
*/
private $sut;
/**
* Runs before each test.
*/
public function setUp() {
$container = wc_get_container();
$container->add( ClassThatDependsOnLegacyCode::class )->addArgument( LegacyProxy::class );
$this->sut = $container->get( ClassThatDependsOnLegacyCode::class );
}
/**
* Legacy proxy's 'call_function' can be used from both an injected LegacyProxy and from 'WC()->call_function'
*
* @param string $method_to_use Method in the tested class to use.
*
* @testWith ["call_legacy_function_using_injected_proxy"]
* ["call_legacy_function_using_woocommerce_class"]
*/
public function test_call_function_can_be_invoked_via_injected_legacy_proxy_and_woocommerce_object( $method_to_use ) {
$this->assertEquals( 255, $this->sut->$method_to_use( 'hexdec', 'FF' ) );
}
/**
* Function mocks can be used from both an injected LegacyProxy and from 'WC()->call_function'
*
* @param string $method_to_use Method in the tested class to use.
*
* @testWith ["call_legacy_function_using_injected_proxy"]
* ["call_legacy_function_using_woocommerce_class"]
*/
public function test_function_mocks_can_be_used_via_injected_legacy_proxy_and_woocommerce_object( $method_to_use ) {
$this->register_legacy_proxy_function_mocks(
array(
'hexdec' => function( $hex_string ) {
return "Mocked hexdec for $hex_string";
},
)
);
$this->assertEquals( 'Mocked hexdec for FF', $this->sut->$method_to_use( 'hexdec', 'FF' ) );
}
/**
* Legacy proxy's 'call_static' can be used from both an injected LegacyProxy and from 'WC()->call_function'
*
* @param string $method_to_use Method in the tested class to use.
*
* @testWith ["call_static_method_using_injected_proxy"]
* ["call_static_method_using_woocommerce_class"]
*/
public function test_call_static_can_be_invoked_via_injected_legacy_proxy_and_woocommerce_object( $method_to_use ) {
$result = $this->sut->$method_to_use( DependencyClass::class, 'concat', 'foo', 'bar', 'fizz' );
$this->assertEquals( 'Parts: foo, bar, fizz', $result );
}
/**
* Static method mocks can be used from both an injected LegacyProxy and from 'WC()->call_function'
*
* @param string $method_to_use Method in the tested class to use.
*
* @testWith ["call_static_method_using_injected_proxy"]
* ["call_static_method_using_woocommerce_class"]
*/
public function test_static_mocks_can_be_used_via_injected_legacy_proxy_and_woocommerce_object( $method_to_use ) {
$this->register_legacy_proxy_static_mocks(
array(
DependencyClass::class => array(
'concat' => function( ...$parts ) {
return "I'm returning concat of these parts: " . join( ' ', $parts );
},
),
)
);
$expected = "I'm returning concat of these parts: foo bar fizz";
$result = $this->sut->$method_to_use( DependencyClass::class, 'concat', 'foo', 'bar', 'fizz' );
$this->assertEquals( $expected, $result );
}
/**
* Legacy proxy's 'get_instance_of' can be used from both an injected LegacyProxy and from 'WC()->call_function'
*
* @param string $method_to_use Method in the tested class to use.
*
* @testWith ["get_instance_of_using_injected_proxy"]
* ["get_instance_of_using_woocommerce_class"]
*/
public function test_get_instance_of_can_be_used_via_injected_legacy_proxy_and_woocommerce_object( $method_to_use ) {
$instance = $this->sut->$method_to_use( \WC_Queue_Interface::class, 34 );
$this->assertInstanceOf( \WC_Action_Queue::class, $instance );
}
/**
* Legacy object mocks can be used from both an injected LegacyProxy and from 'WC()->call_function'
*
* @param string $method_to_use Method in the tested class to use.
*
* @testWith ["get_instance_of_using_injected_proxy"]
* ["get_instance_of_using_woocommerce_class"]
*/
public function test_class_mocks_can_be_used_via_injected_legacy_proxy_and_woocommerce_object( $method_to_use ) {
$mock = new \stdClass();
$this->register_legacy_proxy_class_mocks( array( \WC_Query::class => $mock ) );
$this->assertSame( $mock, $this->sut->$method_to_use( \WC_Query::class ) );
}
}

View File

@ -0,0 +1,105 @@
<?php
/**
* ClassThatDependsOnLegacyCode class file
*
* @package Automattic\WooCommerce\Tests\Proxies\ExampleClasses
*/
namespace Automattic\WooCommerce\Tests\Proxies\ExampleClasses;
use Automattic\WooCommerce\Proxies\LegacyProxy;
/**
* An example class that uses the legacy proxy both from an constructor injected proxy and from the helper methods in the WooCommerce class.
*/
class ClassThatDependsOnLegacyCode {
/**
* The injected LegacyProxy.
*
* @var LegacyProxy
*/
private $legacy_proxy;
/**
* Class constructor.
*
* @param LegacyProxy $legacy_proxy The instance of LegacyProxy to use.
*/
public function __construct( LegacyProxy $legacy_proxy ) {
$this->legacy_proxy = $legacy_proxy;
}
/**
* Use proxy's 'call_function' from the injected proxy.
*
* @param string $function Function to call.
* @param mixed ...$parameters Parameters to pass to the function.
*
* @return mixed The result from the function.
*/
public function call_legacy_function_using_injected_proxy( $function, ...$parameters ) {
return $this->legacy_proxy->call_function( $function, ...$parameters );
}
/**
* Use proxy's 'call_function' using 'WC()->call_function'.
*
* @param string $function Function to call.
* @param mixed ...$parameters Parameters to pass to the function.
*
* @return mixed The result from the function.
*/
public function call_legacy_function_using_woocommerce_class( $function, ...$parameters ) {
return WC()->call_function( $function, ...$parameters );
}
/**
* Use proxy's 'call_static' from the injected proxy.
*
* @param string $class_name Class containing the static method to call.
* @param string $method_name Static method to call.
* @param mixed ...$parameters Parameters to pass to the method.
*
* @return mixed The result from the method.
*/
public function call_static_method_using_injected_proxy( $class_name, $method_name, ...$parameters ) {
return $this->legacy_proxy->call_static( $class_name, $method_name, ...$parameters );
}
/**
* Use proxy's 'call_static' using 'WC()->call_function'.
*
* @param string $class_name Class containing the static method to call.
* @param string $method_name Static method to call.
* @param mixed ...$parameters Parameters to pass to the method.
*
* @return mixed The result from the method.
*/
public function call_static_method_using_woocommerce_class( $class_name, $method_name, ...$parameters ) {
return WC()->call_static( $class_name, $method_name, ...$parameters );
}
/**
* Use proxy's 'get_instance_of' from the injected proxy.
*
* @param string $class_name The name of the class to get an instance of.
* @param mixed ...$args Extra arguments for 'get_instance_of'.
*
* @return object The instance obtained.
*/
public function get_instance_of_using_injected_proxy( string $class_name, ...$args ) {
return $this->legacy_proxy->get_instance_of( $class_name, ...$args );
}
/**
* Use proxy's 'get_instance_of' using 'WC()->call_function'.
*
* @param string $class_name The name of the class to get an instance of.
* @param mixed ...$args Extra arguments for 'get_instance_of'.
*
* @return object The instance obtained.
*/
public function get_instance_of_using_woocommerce_class( string $class_name, ...$args ) {
return WC()->get_instance_of( $class_name, ...$args );
}
}