API Docs for: 0.1.0

lib/plumbing/ConsoleReporter.js

"use strict";

var root = "../..";
var parts = require(root + "/deps/parts");
var ilk = require(root + "/deps/ilk");
var Reporter = require("./Reporter");

require("colors");

var ROW = (function (c, n) {
    var r = [];
    for (var i = 0; i < n; i += 1) {
        r.push(c);
    }

    return r.join("");
}("=", 80));

module.exports = ilk.tokens(function (
    startTime,
    initTime,
    printStack,
    console,
    nowGiver,

    formatEnv,
    log,
    testSummary,
    elapsed,
    row,
    formatError
) {
    /**
     * The console reporter prints the gabarito events to the node's console
     * with colors and what-not.
     *
     * @class gabarito.plumbing.ConsoleReporter
     * @extends gabarito.plumbing.Reporter
     * @constructor
     *
     * @param {Console} [console]
     * @param {function} [nowGiver]
     */
    return Reporter.descend(function (pPrintStack, pConsole, pNowGiver) {
        console.mark(this, pConsole || global.console);
        startTime.mark(this);
        initTime.mark(this);
        printStack.mark(this, arguments.length > 0? pPrintStack: false);
        nowGiver.mark(this, pNowGiver || Date.now);
    }).

    proto(formatEnv, function (env) {
        return "(" + env.getName().yellow + ")";
    }).

    proto(log, function (m) { this[console].log(m); }).

    proto(testSummary, function (results) {
        var summary = {
            failed: 0,
            passed: 0
        };

        parts.forEach(results.results, function (r) {
            if (r.error) {
                summary.failed += 1;
            } else {
                summary.passed += 1;
            }
        });

        return summary;
    }).

    proto(elapsed, function (t) { return (this[nowGiver]() - t) / 1000; }).

    proto(row, function (pass) {
        this[log](ROW[pass? "green": "red"].bold);
    }).

    proto(formatError, function (error) {
        var stack = "";
        if (this[printStack] && error.stack) {
            stack = "\nStack trace:\n" + error.stack;
        }

        return Error.prototype.toString.call(error) + stack;
    }).

    proto({

        /**
         * Prints a row saying that things are starting.
         *
         * @method start
         * @for gabarito.plumbing.ConsoleReporter
         */
        start: function () {
            this[log](ROW.bold);
            this[log]("Starting tests.");
            this[startTime] = this[nowGiver]();
        },

        /**
         * Prints a small summary when things have finished showing the test
         * results.
         *
         * @method finish
         * @for gabarito.plumbing.ConsoleReporter
         *
         * @param {gabarito.EnvironmentResults[]} results
         */
        finish: parts.that(function (that, results) {
            var failed = results.some(function (e) {
                return e.results.some(function (r) {
                    return parts.some(r.results, function (r) {
                        return Boolean(r.error);
                    });
                });
            });

            this[row](!failed);
            this[log]("Finished tests.");
            results.forEach(function (e) {
                var passed = 0;
                var failed = 0;

                e.results.forEach(function (r) {
                    var summary = that[testSummary](r);
                    passed += summary.passed;
                    failed += summary.failed;
                });

                that[log](that[formatEnv](e.environment) + " " +
                        "passed=" + (String(passed).green.bold) + " " +
                        "failed=" + (String(failed).red.bold));
            });

            this[log](("Elapsed time: " +
                    (String(this[elapsed](this[startTime])).bold) +
                    " seconds."));
            this[row](!failed);
            this[log]("");
        }),

        /**
         * Prints a row stating that that n tests will be verified.
         *
         *  @method init
         *  @for gabarito.plumbing.ConsoleReporter
         *
         *  @param {gabarito.plumbing.Environment} env
         *  @param {string[]} tests
         */
        init: function (env, tests) {
            var l = tests.length;
            var msg = this[formatEnv](env) + " " +
                    "verifying " + (String(l).green.bold) + " " +
                    (l === 1? "test.": "tests.");

            this[initTime] = this[nowGiver]();

            this[log](ROW.yellow.bold);
            this[log](msg);
        },

        /**
         * Prints a row stating which test is about to be verified.
         *
         * @method begin
         * @for gabarito.plumbing.ConsoleReporter
         *
         * @param {gabarito.plumbing.Environment} env
         * @param {string} test
         */
        begin: function (env, test) {
            var msg = this[formatEnv](env) + " " +
                    "verifying " + (test.bold) + ".";

            this[log](ROW.bold);
            this[log](msg);
        },

        /**
         * Prints a small summary for the test that has ended.
         *
         * @method end
         * @for gabarito.plumbing.ConsoleReporter
         *
         * @param {gabarito.plumbing.Environment} env
         * @param {string} test
         * @param {gabarito.TestResult} results
         */
        end: function (env, test, results) {
            var summary = this[testSummary](results);

            var msg = this[formatEnv](env) + " " +
                    "test summary: " +
                    ("passed: " + summary.passed).bold.green +
                    " " +
                    ("failed: " + summary.failed).bold.red;

            this[row](summary.failed === 0);
            this[log](msg);
            this[row](summary.failed === 0);
            this[log]("");
        },

        /**
         * Prints a summary for the environment when it has completed.
         *
         * @method complete
         * @for gabarito.plumbing.ConsoleReporter
         *
         * @param {gabarito.plumbing.Environment} env
         * @param {gabarito.TestResult[]} results
         */
        complete: parts.that(function (that, env, results) {
            var tests = results.length;
            var summary = {
                passed: 0,
                failed: 0
            };

            results.forEach(function (r) {
                var s = that[testSummary](r);
                summary.passed += s.passed;
                summary.failed += s.failed;
            });

            this[row](summary.failed === 0);
            this[log]("Environment summary: " + (env.getName().yellow.bold));
            this[log]("Tests: " + (String(tests).bold));
            this[log](("Passed clauses: " +
                    (String(summary.passed).bold)).green);
            this[log](("Failed clauses: " + (String(summary.failed).bold)).red);
            this[log](("Elapsed time: " +
                    (String((this[nowGiver]() - this[initTime]) / 1000).bold) +
                    " seconds."));
            this[row](summary.failed === 0);
            this[log]("");
        }),

        /**
         * Prints a green line stating that the test clause has passed
         *
         * @method pass
         * @for gabarito.plumbing.ConsoleReporter
         *
         * @param {gabarito.plumbing.Environment} env
         * @param {string} test
         * @param {string} clause
         * @param {gabarito.ClauseResult} result
         */
        pass: function (env, test, clause, result) {
            var msg = this[formatEnv](env) + " " +
                    (("[" + "PASS".green + "] ").bold) + test + " :: " + clause;
            this[log](msg);
        },

        /**
         * Prints a red line stating that the test clause has failed.
         *
         * @method fail
         * @for gabarito.plumbing.ConsoleReporter
         *
         * @param {gabarito.plumbing.Environment} env
         * @param {string} test
         * @param {string} clause
         * @param {gabarito.ClauseResult} result
         */
        fail: function (env, test, clause, result) {
            var msg = this[formatEnv](env) + " " +
                    (("[" + "FAIL".red + "] ").bold) + test + " :: " +
                    clause;
            this[log](msg);
            this[log](this[formatError](result.error).red);
        },

        /**
         * Prints the environment's name and every argument on a new line.
         *
         * @method say
         * @for gabarito.plumbing.ConsoleReporter
         *
         * @param {gabarito.plumbing.Environment} env
         * @param {string} args*
         */

        say: parts.args(parts.that(function (that, args) {
            var env = args.shift();

            this[log](this[formatEnv](env) + " says...");
            args.forEach(function (m) { that[log](m); });
        })),

        /**
         * Prints a message stating that the environment issued an error and
         * prints the error itself in red.
         *
         * @method error
         * @for gabarito.plumbing.ConsoleReporter
         *
         * @param {gabarito.plumbing.Environment} env The environment
         * @param {mixed} error
         */
        error: function (env, error) {
            this[log](this[formatEnv](env) + " issued an error:");
            this[log](this[formatError](error).red);
        }
    });
});