Chronicles of a build - the signup plugin 08

Disclaimer

What I write in these posts is not the perfect travel of an expert and consumed WordPress developer but the gnarly and error-prone stroll of an average developer (pun intended).
I will make mistakes and will try to correct them along the road and mean to share the path I’ve taken with all its fallback and wrong turns and not to show the best possible one.

Follow along

After setting up the plugin using grunt-init I’ve deployed it in my local site and made it available on GitHub. I will commit to the GitHub repository throughout the work and the plugin can be downloaded and installed in WordPress. The code I show becomes much more comprehensible when observed in context.

The practice of breaking down the class

In my earlier post I’ve defined two questions that need an answer when deciding to test code:

  1. Do I want to test it?
  2. If so: can I test it?

Beginning with the plugin admin-side class, defined in the file /includes/class-member_signup_admin.php, I look inside each method for the functions and variables calls it makes, answer question 1 and if positive answer question 2. If I can’t actually test the code I refactor it to make it testable.
I begin with the __construct method, this are its calls:

membersignup::get_instance (class method)
get_plugin_slug (instance method)
add_action (WP function)
add_filter (WP function)

membersignup::get_instance

It’s a call to a singleton class and its main singleton access method. In that class I might be testing that the singleton pattern works but here I do not need to test it.

get_plugin_slug

I do not want to test it because it takes no parameters and its calling is implicit in the code. It’s an internal call that will be called each time __construct runs and right now I do not see much utility in testing it.

add_action and add_filter

I want to know if and how many times this method gets called and, maybe, even the arguments of the call: it should be called only once and no more since the class has its main access point in get_instance.
I can’t test it as is and should mock the global function using runkit: I will create an adapter class to be able to mock that adapter class in tests.

Creating the first adapter class

Seen the code requirements above I create an adapter class that merely wraps the WordPress methods to add actions and filters (I have removed inline comments for brevity)

class adclasses_Filters {

    protected static $instance = null;

    public static function get_instance() {

        // If the single instance hasn't been set, set it now.
        if ( null == self::$instance ) {
            self::$instance = new self;
        }
        return self::$instance;
    }

    public static function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
        return add_filter($tag, $function_to_add, $priority, $accepted_args);
    }

    public static function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) {
        return add_filter($tag, $function_to_add, $priority, $accepted_args);
    }
}

and invoke it in my refactored construct method

$this->filters->add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_styles' ) );

My code is still not testable due to dependencies but this is a step toward it.

Small classes for me

In the tag I had applied to previous commits, first_UA_green_light, the plugin sported two big classes with mixed responsibilities (commmon practice in WordPress) while the later tag, broke_into_smaller_classes, lists 6. OOP is not a WordPress common practice and when used moloch all-doing classes are common. I like to keep my classes stupid, simple and little in size and responsibilities for two reasons:

  1. I can immediately know what a class does, think of class-plugin-admin_main and class-redirects
  2. I can read smaller files better and since developers spend more time reading code than writing it making my code readable to me and others is an investment that will pay later.

Adapters are on GitHub

The whole point in OOP is to re-use common components and re-creating adapter classes for each project, even using a templating tool like grunt-init is an exercise in redundancy; to this end I put on GitHub a plugin for WordPress that loads adapter classes to be used in plugins. Actually the methods wrapped are the ones needed for this plugin but more will follow as the development progresses or contributors jump on the wagon.
The wrapping of WordPress defined methods is so blatantly that methods of wrapping classes have the same name of the WordPress methods they call.