gruntmock

    0.2.1 • Public • Published

    gruntMock

    A simple mock for testing Grunt multi-tasks.

    npm version GitHub tag Build status Coverage License

    Overview

    Some Grunt tasks are thin wrappers over functionality that's already well tested (ex: grunt-contrib-jshint). Other Grunt tasks offer custom functionality, specialized behavior, or need their output to be verified. gruntMock is targeted at the second set and offers a way to validate the complete, end-to-end lifecycle of a Grunt multi-task.

    gruntMock is simple mock object that simulates the Grunt task runner for multi-tasks and can easily be integrated into a unit testing environment such as Nodeunit. gruntMock invokes tasks the same way Grunt does and exposes (almost) the same set of APIs. After providing input to a task, gruntMock runs and captures its output so tests can verify expected behavior. Task success and failure are unified, so it's easy to write positive and negative tests.

    Example

    var gruntMock = require('gruntmock');
    var example = require('./example-task.js');
     
    exports.exampleTest = {
     
      pass: function(test) {
        test.expect(4);
        var mock = gruntMock.create({
          target: 'pass',
          files: [
            { src: ['unused.txt'] }
          ],
          options: { str: 'string', num: 1 }
        });
        mock.invoke(example, function(err) {
          test.ok(!err);
          test.equal(mock.logOk.length, 1);
          test.equal(mock.logOk[0], 'pass');
          test.equal(mock.logError.length, 0);
          test.done();
        });
      },
     
      fail: function(test) {
        test.expect(2);
        var mock = gruntMock.create({ target: 'fail' });
        mock.invoke(example, function(err) {
          test.ok(err);
          test.equal(err.message, 'fail');
          test.done();
        });
      }
    };

    Mocking

    Some of Grunt's APIs are self-contained and don't need special handling (ex: grunt.file), so gruntMock exposes the original implementation via a pass-through. Other APIs need to be captured or redirected for test purposes (ex: grunt.log), so gruntMock returns a custom implementation. Other APIs are complicated or uncommon enough that gruntMock doesn't try to support them (ex: grunt.task).

    Interface

    /**
     * Creates an instance of GruntMock.
     *
     * @param {Object} config Configuration object (target, files, options, data).
     * @return {GruntMock} A new instance of GruntMock.
     */
    var gruntMock = GruntMock.create(config)
     
    /**
     * Mocks Grunt and invokes a multi-task.
     *
     * @param {Function} task A Grunt multi-task.
     * @param {Function} callback A callback(err, mock) function.
     */
    gruntMock.invoke(task, callback)
     
    /**
     * Array of all error messages a task logs.
     */
    gruntMock.logError
     
    /**
     * Array of all non-error messages a task logs.
     */
    gruntMock.logOk

    Supported APIs

    grunt

    • registerMultiTask
    • warn
    • fatal
    • option
    • package
    • version

    grunt.event

    • All methods (via pass-through)

    grunt.fail

    • All methods

    grunt.file

    • All methods (via pass-through)

    grunt.log

    • All methods (with helpers via pass-through)

    grunt.option

    • All methods (via pass-through)

    grunt.task

    • registerMultiTask

    grunt.template

    • All methods (via pass-through)

    grunt.util

    • All methods (via pass-through)

    Inside Tasks

    • args (see note below)
    • async
    • data
    • errorCount
    • files (see note below)
    • filesSrc
    • flags (see note below)
    • name
    • nameArgs
    • options
    • target

    Notes

    • gruntMock supports both synchronous and asynchronous task execution. gruntMock's invoke method always calls its callback asynchronously.
    • The files input uses Grunt's array format. Globbing is not handled by gruntMock because it's outside the scope of testing a Grunt task. Test input can be provided un-globbed for the same effect.
    • Although grunt.log.warn behaves like grunt.log.error, it does not increment this.errorCount, so its output is logged to gruntMock.logOk.
    • gruntMock unconditionally captures and reports verbose/debug output along with normal log output. Differentiating among normal/verbose/debug output is not currently supported.
    • Grunt's --force option is not supported; a call to grunt.warn.fatal or an unhandled exception always ends the task.
    • this.args and this.flags are unused and always empty.

    License

    MIT

    Releases

    • 0.1.0 - Initial release.
    • 0.1.1 - Lower-case package name per npm policy.
    • 0.2.0 - Add support for this.data inside a task.
    • 0.2.1 - Update to work with Grunt 1.0.0 release.

    Install

    npm i gruntmock

    DownloadsWeekly Downloads

    3

    Version

    0.2.1

    License

    MIT

    Last publish

    Collaborators

    • davidanson