Source: core.js

/**
 * BDD EDSL for the Specify framework.
 *
 * @module specify-dsl-bdd/lib/core
 */
// -- Dependencies -----------------------------------------------------
var Future = require('data.future');
var Maybe = require('data.maybe');
var Async = require('control.async')(Future);
var Lambda = require('core.lambda');
var Base = require('boo').Base;
var adt = require('adt-simple');
// -- Aliases ----------------------------------------------------------
var curry = Lambda.curry;
var fail = Future.rejected;
var fromPromise = Async.fromPromise;
var liftNode = Async.liftNode;
// -- Core implementation ----------------------------------------------
/**
 * A list of supported implementations for asynchronous interfaces.
 *
 * @class
 * @summary
 * type Interface = Promise | Node | Future
 */
var Interface = function () {
        function Interface$2() {
        }
        function Promise$2() {
        }
        Promise$2.prototype = new Interface$2();
        Promise$2.prototype.constructor = Promise$2;
        function Node$2() {
        }
        Node$2.prototype = new Interface$2();
        Node$2.prototype.constructor = Node$2;
        function Future$2() {
        }
        Future$2.prototype = new Interface$2();
        Future$2.prototype.constructor = Future$2;
        var derived = adt.Base.derive({
                name: 'Interface',
                constructor: Interface$2,
                prototype: Interface$2.prototype,
                variants: [
                    {
                        name: 'Promise',
                        constructor: Promise$2,
                        prototype: Promise$2.prototype
                    },
                    {
                        name: 'Node',
                        constructor: Node$2,
                        prototype: Node$2.prototype
                    },
                    {
                        name: 'Future',
                        constructor: Future$2,
                        prototype: Future$2.prototype
                    }
                ]
            });
        Interface$2.Promise = new derived.variants[0].constructor();
        Interface$2.Node = new derived.variants[1].constructor();
        Interface$2.Future = new derived.variants[2].constructor();
        return Interface$2;
    }();
var Promise = Interface.Promise;
var Node = Interface.Node;
var Future = Interface.Future;
/**
 * Constructs a DSL implementation for the given interface.
 *
 * @method
 * @private
 * @summary Interface → Specify.Core → DSL
 */
function makeDSL(asyncInterface, specify) {
    var Hook = specify.Hook;
    var TestSuite = specify.Test.Suite;
    var TestCase = specify.Test.Case;
    /**
   * The DSL interface.
   *
   * @namespace DSL
   */
    var DSL = {};
    // -- Objects --------------------------------------------------------
    /**
   * Represents a test Suite.
   *
   * @memberof! DSL
   * @class
   * @summary
   * type Suite <| Boo.Base {
   *   name       :: String
   *   tests      :: [Suite | Test]
   *   beforeEach :: [Future(Error, Void)]
   *   afterEeach :: [Future(Error, Void)]
   *   beforeAll  :: [Future(Error, Void)]
   *   afterAll   :: [Future(Error, Void)]
   * }
   */
    var Suite = Base.derive({
            init: function _init(name) {
                this.name = name;
                this.tests = [];
                this.beforeEach = [];
                this.afterEach = [];
                this.beforeAll = [];
                this.afterAll = [];
            },
            construct: function () {
                return TestSuite.create({
                    name: this.name,
                    tests: this.tests.map(function (a) {
                        return a.construct();
                    }),
                    beforeAll: Hook(this.beforeAll),
                    afterAll: Hook(this.afterAll),
                    beforeEach: Hook(this.beforeEach),
                    afterEach: Hook(this.afterEach)
                });
            }
        });
    /**
   * Represents a test Case.
   *
   * @class
   * @summary
   * type Test <| Boo.Base {
   *   name    :: String
   *   test    :: Future(Error, Void)
   *   timeout :: Maybe(&lt;Number/ms&gt;)
   *   slow    :: Maybe(&lt;Number/ms&gt;)
   *   enabled :: Maybe(Case → Boolean)
   * }
   */
    var Test = Base.derive({
            init: function _init(name, test) {
                this.name = name;
                this.test = test;
                this.slow = new Maybe.Nothing();
                this.timeout = new Maybe.Nothing();
                this.enabled = new Maybe.Nothing();
            },
            construct: function () {
                return TestCase.create({
                    name: this.name,
                    test: this.test,
                    slow: this.slow,
                    timeout: this.timeout,
                    enabled: this.enabled
                });
            },
            enable: function () {
                return this.enableWhen(function (_) {
                    return true;
                });
            },
            disable: function () {
                return this.enableWhen(function (_) {
                    return false;
                });
            },
            enableWhen: function (f) {
                this.enabled = new Maybe.Just(f);
                return this;
            },
            setSlow: function (a) {
                this.slow = new Maybe.Just(a);
                return this;
            },
            setTimeout: function (a) {
                this.timeout = new Maybe.Just(a);
                return this;
            }
        });
    // -- Interface ------------------------------------------------------
    spec = curry(3, spec);
    function spec(parent, name, body) {
        var suite = Suite.make(name);
        body.call(makeContext(suite), it(suite), spec(suite));
        parent.tests.push(suite);
        return suite;
    }
    it = curry(3, it);
    function it(parent, name, code) {
        var action = new Future(function (reject, resolve) {
                try {
                    resolve(code());
                } catch (e) {
                    reject(e);
                }
            });
        var test = Test.make(name, action);
        parent.tests.push(test);
        return test;
    }
    asyncFuture = curry(3, asyncFuture);
    function asyncFuture(parent, name, code) {
        var test = Test.make(name, code);
        parent.tests.push(test);
        return test;
    }
    asyncPromise = curry(3, asyncPromise);
    function asyncPromise(parent, name, code) {
        var test = Test.make(name, fromPromise(code()));
        parent.tests.push(test);
        return test;
    }
    asyncNode = curry(3, asyncNode);
    function asyncNode(parent, name, code) {
        var test = Test.make(name, liftNode(code)());
        parent.tests.push(test);
        return test;
    }
    beforeEach = curry(2, beforeEach);
    function beforeEach(parent, code) {
        parent.beforeEach.push(code);
    }
    afterEach = curry(2, afterEach);
    function afterEach(parent, code) {
        parent.afterEach.push(code);
    }
    beforeAll = curry(2, beforeAll);
    function beforeAll(parent, code) {
        parent.beforeAll.push(code);
    }
    afterAll = curry(2, afterAll);
    function afterAll(parent, code) {
        parent.afterAll.push(code);
    }
    function makeContext(parent) {
        return {
            it: it(parent),
            spec: spec(parent),
            async: selectAsync()(parent),
            asyncPromise: asyncPromise(parent),
            asyncNode: asyncNode(parent),
            asyncFuture: asyncFuture(parent),
            beforeEach: beforeEach(parent),
            afterEach: afterEach(parent),
            beforeAll: beforeAll(parent),
            afterAll: afterAll(parent)
        };
    }
    function selectAsync() {
        return function (a0) {
            if (Promise.hasInstance ? Promise.hasInstance(a0) : a0 instanceof Promise) {
                return asyncPromise;
            }
            if (Node.hasInstance ? Node.hasInstance(a0) : a0 instanceof Node) {
                return asyncNode;
            }
            if (Future.hasInstance ? Future.hasInstance(a0) : a0 instanceof Future) {
                return asyncFuture;
            }
            throw new TypeError('No match');
        }.call(this, asyncInterface);
    }
    return function (name, body) {
        var root = Suite.make(name);
        body.call(makeContext(root), it(root), spec(root));
        return root.construct();
    };
}
// -- Exports ----------------------------------------------------------
var dsl = module.exports = curry(2, makeDSL);
dsl.promise = dsl(Promise);
dsl.node = dsl(Node);
dsl.future = dsl(Future);
dsl.Interface = Interface;
//# sourceMappingURL=core.js.map