Skip to content

Commit

Permalink
Introduce a Container Singleton, + unit tests
Browse files Browse the repository at this point in the history
  • Loading branch information
freibergergarcia committed Feb 11, 2024
1 parent 5c62e6b commit 8094289
Show file tree
Hide file tree
Showing 6 changed files with 235 additions and 15 deletions.
5 changes: 3 additions & 2 deletions .wp-env.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"core": null,
"phpVersion": "8.0",
"core": "WordPress/WordPress",
"phpVersion": "8.1",
"plugins": [ "." ],
"env": {
"tests": {
"phpVersion": "8.1",
"config": {
"FS_METHOD": "direct",
"WP_DEBUG": true,
Expand Down
7 changes: 2 additions & 5 deletions custom-post-types-taxonomies.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@

declare( strict_types=1 );

use Custom_PTT\Container_Singleton;
use Custom_PTT\Plugin_Factory;

if ( ! defined( 'ABSPATH' ) ) {
Expand Down Expand Up @@ -65,11 +66,7 @@
* @throws Exception
*/
function bootstrap_plugin(): void {

$container_builder = new DI\ContainerBuilder();
$container_builder->addDefinitions( __DIR__ . '/config/di-config.php' );
$container = $container_builder->build();

$container = Container_Singleton::get_instance();
Plugin_Factory::create( $container )
->boot();
}
Expand Down
52 changes: 52 additions & 0 deletions includes/Container_Singleton.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare( strict_types=1 );

namespace Custom_PTT;

use DI\Container;
use DI\ContainerBuilder;
use Exception;

/**
* Container_Singleton class.
*
* This class is a placeholder for a singleton container instance.
*
* @package Custom_PTT
* @since 0.2.1
*/
class Container_Singleton {
/**
* The Container instance.
*
* @var Container|null
*
* @since 0.2.1
*/
private static ?Container $container = null;

/**
* Prevent class from being instantiated.
* @since 0.2.1
*/
private function __construct() {}

/**
* Get the Container instance.
*
* @return Container
* @throws Exception
*
* @since 0.2.1
*/
public static function get_instance(): Container {
if ( null === static::$container ) {
$container_builder = new ContainerBuilder();
$container_builder->addDefinitions( __DIR__ . '/../config/di-config.php' );
static::$container = $container_builder->build();
}

return static::$container;
}
}
71 changes: 71 additions & 0 deletions tests/unit/Container_Singleton_Test.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare( strict_types=1 );

namespace Custom_PTT\Tests\Unit;

use Custom_PTT\Container_Singleton;
use DI\Container;
use Exception;
use ReflectionClass;
use WP_UnitTestCase;

/**
* Class Container_Singleton_Test
*
* @package Custom_PTT\Tests\Unit
* @since 0.2.1
*/
class Container_Singleton_Test extends WP_UnitTestCase {

/**
* Resets the container instance before each test, as it's created on plugin bootstrap
*
* @return void
*
* @since 0.2.1
*/
public function setUp(): void {
parent::setUp();

$reflection = new ReflectionClass( Container_Singleton::class );
$container = $reflection->getProperty( 'container' );
$container->setAccessible( true );
$container->setValue( null, null );
}

/**
* Test that get_instance returns a Container instance.
*
* @throws Exception
*
* @since 0.2.1
*/
public function test_get_instance_returns_container_instance() {
$instance = Container_Singleton::get_instance();
$this->assertInstanceOf( Container::class, $instance );
}

/**
* Test that get_instance always returns the same instance.
*
* @throws Exception
*
* @since 0.2.1
*/
public function test_get_instance_returns_same_instance() {
$first_call_instance = Container_Singleton::get_instance();
$second_call_instance = Container_Singleton::get_instance();

$this->assertSame( $first_call_instance, $second_call_instance );
}

/**
* @return void
*
* @since 0.2.1
*/
public function tearDown(): void {
parent::tearDown();
}
}
92 changes: 89 additions & 3 deletions tests/unit/Plugin_Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,108 @@

namespace Custom_PTT\Tests\Unit;

use Custom_PTT\Container_Singleton;
use Custom_PTT\Plugin;
use Custom_PTT\Plugin_Factory;
use DI\Container;
use DI\DependencyException;
use DI\NotFoundException;
use Exception;
use WP_UnitTestCase;

/**
* Class Plugin_Test
*
* @package Custom_PTT\Tests\Unit
* @since 0.1.0-alpha
*/
class Plugin_Test extends WP_UnitTestCase {

private Plugin $plugin;
/**
* Container instance.
*
* @var Container
*
* @since 0.2.1
*/
private Container $container;

/**
* Plugin instance.
*
* @var Plugin
*
* @since 0.2.1
*/
private Plugin $plugin;

/**
* Set up
*
* @return void
*
* @throws Exception
* @since 0.1.0-alpha
*/
public function setUp(): void {
parent::setUp();

$this->container = $this->createMock( Container::class );
$this->plugin = new Plugin( $this->container );
$this->container = Container_Singleton::get_instance();
$this->plugin = Plugin_Factory::create( $this->container );
}

/**
* Test plugin instance is created
*
* @return void
*
* @since 0.2.1
*/
public function test_plugin_instance_is_created() {
$this->assertInstanceOf( Plugin::class, $this->plugin );
}

/**
* Test boot register activation and deactivation hooks
*
* @throws Exception
*
* @since 0.2.1
*/
public function test_boot_method_registers_hooks() {

$this->plugin->boot();

$file = plugin_basename( CUSTOM_PTT_FILE );

$this->assertEquals( 10, has_action( 'activate_' . $file, array( $this->plugin, 'on_activation' ) ) );
$this->assertEquals( 10, has_action( 'deactivate_' . $file, array( $this->plugin, 'on_deactivation' ) ) );
}

/**
* Test all services are registered
*
* @since 0.2.1
*/
public function test_register_services_method_registers_services() {
$services = $this->container->getKnownEntryNames();

if ( empty( $services ) ) {
$this->fail( 'No services found' );
}

foreach ( $services as $service ) {
$this->assertTrue( $this->container->has( $service ) );
}
}

/**
* Tear down
*
* @return void
*
* @since 0.1.0-alpha
*/
public function tearDown(): void {
parent::tearDown();
}
Expand Down
23 changes: 18 additions & 5 deletions tests/unit/bootstrap.php
Original file line number Diff line number Diff line change
@@ -1,21 +1,34 @@
<?php


define( 'TESTS_PLUGIN_DIR', dirname( __DIR__, 2 ) );
$_test_root = getenv( 'WP_TESTS_DIR' );

if ( false === getenv( 'WP_TESTS_DIR' ) ) {
exit( 'WP_TESTS_DIR environment variable is not set. Please set it to the root of your WordPress installation.' );
}

define( 'TESTS_PLUGIN_DIR', dirname( __DIR__, 2 ) );

if ( ! file_exists( TESTS_PLUGIN_DIR . '/vendor/autoload.php' ) ) {
exit( 'The vendor directory is missing. Please run composer install.' );
}

if ( ! file_exists( $_test_root . '/includes/bootstrap.php' ) ) {
exit( 'Could not load /includes/bootstrap.php' );
}

require TESTS_PLUGIN_DIR . '/vendor/autoload.php';

$_test_root = getenv( 'WP_TESTS_DIR' );
define( 'WP_TESTS_PHPUNIT_POLYFILLS_PATH', dirname( __DIR__, 2 ) . '/vendor/yoast/phpunit-polyfills' );

if ( ! file_exists( $_test_root . '/includes/bootstrap.php' ) ) {
exit( 'Could not load /includes/bootstrap.php' );
require_once $_test_root . '/includes/functions.php';

/**
* Manually load the plugin being tested.
*/
function _manually_load_plugin(): void {
require dirname( __DIR__, 2 ) . '/custom-post-types-taxonomies.php';
}

tests_add_filter( 'muplugins_loaded', '_manually_load_plugin' );

require $_test_root . '/includes/bootstrap.php';

0 comments on commit 8094289

Please sign in to comment.