In the last post I detailed how I put together the Paged Plugin for DocPad. After I got the plugin up and running on my own site, I decided I’d give back to the community and publish it on NPM for everyone to use. This entailed pulling the plugin out into a standalone module, and getting the unit testing working so I knew it was all good to go.
In order to do this I first had to setup the following folder structure:
package.json remains mostly the same as in previous exmaples with a small addition:
devDependencies object specfies dependencies we have for development purposes only, in this case we need CoffeeScript to compile the plugin. The
scripts object specifies the test runner that
npm will use to test the plugin.
Note that I’ve added a
Makefile to the folder, this is fairly standard for all DocPad plugins and I copied it from one of the existing ones.
The source for our plugin is now in the
src folder in the
paged.plugin.coffee file as before, I’ve also added some files here for testing purposes which I’ll explain in more detail.
Since I’m releasing this code out into the wild it might also be wise to make sure it works so lets setup some unit testing. Thankfully DocPad has made this quite easy once you know how, with a suite of basic tests and expected output tests ready to roll so you don’t have to do much to make sure your plugin is working correctly.
First we must create a ‘tester’ for our plugin, this is defined in the new
# Export Plugin Tester
Notice here we’re extending from the testers.RendererTester class. This is provided by DocPad and is designed to execute the plugin on a collection of documents and tests its output against a folder of expected results (
out-expected). To figure out exactly how this works you might want to take a look at the source available here. But all you really need to know is the
docpadConfig is used to configure an instance of DocPad to be used during testing, so here we enable our plugin and anything else we’ll need in our tests.
Next we need to sort out our
test folder which will actually contain and specify our tests. First up is our
package.json file in the
test folder, this is used to specify the dependencies for the test and to allow NPM to hook everything up for us:
Now we can specify our actual test case in our
All this does is get access to the testers module provided by DocPad and execute the test function passing in a configuration that tells DocPad how to run our plugin tests. All you actually have to specify is the
pluginPath which in this case simply points to the parent folder which contains our plugins
package.json and a
pluginName which allows DocPad to properly instantiate our plugin. If you don’t specify a
pluginName property then DocPad will try and use the folder name of the plugin folder (in my case thats
docpad-plugin-paged which does not match the filenames I used in my plugin).
Now for the content of the tests. Since we’re using the RendererTester the test will consist of instanatiating a copy of DocPad and running it over the contents of the
/test/src/documents folder and then comparing the resulting documents with the ones found in
/test/out-expected. So simply place some documents in the folder and set it up as you would expect, for my simplest test I did the following in a file called
This exercises my plugin by making it generate 3 pages each containing 2 documents, outputting a little HTML in each one. In order to make the test pass I just need to add the expected output to the appropriate folder each file goes a little somethind like this:
<header>Page 1 of 3 : Documents [0,1]</header>
See the source for more details.
So we’ve setup the appropriate file structure, and added our tests. How do we actually execute them? Well its quite simple, but it requires a little more setup than you would hope at first. Because we added the
test script to our
package.json specifying a path to the test file we can use the command
npm test to execute our test suite. However if you run that now you’ll probably get an error message of some sort:
$ npm test
Not good. In order to get this working I had to turn to Benjamin Lupton the creator of DocPad for some answers. In short to setup the testing structure we need to get the development version of DocPad, compile it, and setup symlinks so that your plugin tests can use it. So to get everything setup you’ll need to install the DocPad source, and setup a symlink to it, thankfully this is quite easy:
git clone https://github.com/bevry/docpad.git- Clone the DocPad respository into your workspace (not your plugin folder)
cd docpad- move into the new folder
npm install -g coffee-script- install coffee script so we can build docpad
cake setup- setup the dev environment for compiling
npm link- link the DocPad folder you have now created into npm, this means when you use DocPad on your machine it points to this working folder
cake compile- compile DocPad so its ready to use
Now we need to do something similar for your plugin:
cd docpad-plugin-paged- move into the folder for your plugin
npm install- install the dependencies for your plugin
npm link docpad- add the linked version of DocPad to your plugins dependencies
make compile- compile your plugin
make test- run the tests!
Hopefully your tests should now run and pass!
To round everything out I simply added some details to my
README.md file and added an
.npmignore file to my folder containing the following:
This just tells npm to ignore my test folders and other things that are unnecessary. I then setup my user account on https://npmjs.org/signup and added my user account details to my npm installation with
npm adduser. After that publishing to npm is accomplished with the
npm publish command.
There you have it, a fully tested, published plugin for DocPad. Hopefully this will be the first of many, I’ve a few other ideas for things I’d like to see in the project so we’ll see if I can find time to make them. If you are trying to get a DocPad plugin up and running and are having problems give me a shout, or drop into talk to the incredibly helpful DocPad guys on the irc.freenode.org server channel #docpad.