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

Add module loader initial tests #2

Open
wants to merge 2 commits into
base: feature/cert-builder
Choose a base branch
from

Conversation

eri-trabiccolo
Copy link

@eri-trabiccolo eri-trabiccolo commented Oct 31, 2019

also add LLMS_Module_Loader::$instance->is_module_loaded($name) as a way to
check if a module has been loaded.

also add LLMS_Module_Loader::$instance->is_module_loaded($name) as a way to
check if a module has been loaded.
Comment on lines 19 to 48
public function test_load() {

// get modules to be loades.
$modules = $this->_get_load_info();

// check they've been loaded.
foreach ( $modules as &$module ) {
$module['actions'] = did_action( "lifterlms_module_{$module['name']}_loaded" );
$this->assertEquals( 1, $module['actions'] );
LLMS_Module_Loader::instance()->is_module_loaded( $module['name'] );
}

// define module constants to false so to skip the loading.
foreach ( $modules as $module ) {
! defined( $module['constant_name'] ) && define( $module['constant_name'], FALSE );
}

// Fire the loading once again.
$loaded = LLMS_Unit_Test_Util::call_method( LLMS_Module_Loader::instance(), 'load' );

// check they've not been loaded this time.
$this->assertEquals( array(), $loaded );

foreach ( $modules as &$module ) {
$actions_counter = $module['actions'];
$module['actions'] = did_action( "lifterlms_module_{$module['name']}_loaded" );
$this->assertEquals( $actions_counter, $module['actions'] );
}

}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I'm having difficulties in understanding. Is there a way I can write separate tests, test_load() and test_do_not_load()? Because there are two possible scenarios in the real use:

  1. If constant is defined to false, the module must not get loaded, at all.
  2. If no constant is defined, module must get loaded.

Both these scenarios need to work and therefore, need to be tested.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we add a dummy module within the test suite and filter https://github.com/actual-saurabh/lifterlms/blob/feature/cert-builder/includes/modules/class-llms-module-loader.php#L111 to remove every other module and supply this dummy's information instead?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is what I'm having difficulties in understanding. Is there a way I can write separate tests, test_load() and test_do_not_load()? Because there are two possible scenarios in the real use:

  1. If constant is defined to false, the module must not get loaded, at all.
  2. If no constant is defined, module must get loaded.

Both these scenarios need to work and therefore, need to be tested.

Sorry, probably my comments in the code are not clear. Let me explain:
The code above checks both that the modules are loaded if no constant is defined (which is the default) and that the modules are NOT LOADED when defining the respective constants to false (see the piece of code that starts from // define module constants to false so to skip the loading.).

I see understanding what that test does and why it does it that way can be tricky, but let me try to explain:
The unit tests bootstrapping right now is done in a way that the actual unit test classes are loaded AFTER WordPress is loaded, so when the method above test_load() is executed, the plugin's LLMS_Module_Loader class has been already instantiated.

So LLMS_Module_Loader::$instance->load() has already been executed once. So what I can do is just checking the modules I expected to be loaded have been actually loaded, and I check that with the "tools" the LLMS_Module_Loader gives me: it fires specific actions when modules are loaded, and I check that did_action('action') is equal to the number of times that action has been triggered, in our case, we expect that equals to 1.

Then I want to test that setting a specific constant to false will prevent a module from being loaded. How can I?
(Remember that, as of now, for what I said above about the unit tests bootstrapping etc., I have no to prevent the first load.)
I define the modules constants as false and emulate a new load by manually calling the LLMS_Module_Loader::$instance->load() method, and then check that:

  1. the modules are not loaded: the result of the method LLMS_Module_Loader::$instance->load() is an empty array.
  2. (redundant) the did_action('action') for each module is the same as before => meaning that the action has not been triggered this time.

Still because of the bootstrapping thing, to perform the tests based on the constants, it's mandatory that we don't define those constants the first time we trigger the LLMS_Module_Loader::$instance->load() method. I cannot undefine a constant, and I cannot perform any before the LLMS_Module_Loader::$instance->load() method is fired the first time. The tricky part of the unit tests is that we have to write code that can be tested. :D

p.s.
to do something before wp and lifterlms plugins are loaded we have to act on the bootstrapping file here (the load method):
https://github.com/gocodebox/lifterlms/blob/3d088e89b41e59641dab1e86ca948b6bfd0087fe/tests/bootstrap.php

But you can see that 'place' is pretty generic and defining specific constants for a specific test there is not ideal to me.

Can we add a dummy module within the test suite and filter https://github.com/actual-saurabh/lifterlms/blob/feature/cert-builder/includes/modules/class-llms-module-loader.php#L111 to remove every other module and supply this dummy's information instead?

Yes we can, sure, we can add them here:
https://github.com/gocodebox/lifterlms/tree/master/tests/assets
Actually I think we can touch and then remove files with php api. I'm going to look into this and add a new commit to this PR.

Hope I've been clear. Let me know if otherwise.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

added dummy modules tests

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it make things better if I remove these lines from the module loader: https://github.com/actual-saurabh/lifterlms/blob/feature/cert-builder/includes/modules/class-llms-module-loader.php#L118-L126 and shift the responsibility of setting up and checking the constant into the module itself?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess the problem would still be the same.
Once a constant is defined we cannot "unset" it. And since a first load happen before our tests start the constant gets defined... and we're back to square one.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants