UNPKG

fudi

Version:

101 ways to encode/decode FUDI

163 lines (140 loc) 3.7 kB
/* --- script: suite.js description: test-suite class license: MIT-style license authors: - Mark Obcena provides: [Suite] ... */ (function(){ var checkArg = require('./utils').checkArg, Case = require('./case').Case, Spy = require('./spy').Spy; var Suite = function(name, body, callbacks, argCheck){ if (argCheck && !checkArg('it', body)) throw new SyntaxError('Suite function does not explicitly define an `it` argument.'); this.$argCheck = argCheck; this.name = name; this.$body = body; this.$tests = []; this.$results = []; this.$context = { createSpy: function(fn, bound){ return new Spy(fn, bound); } }; this.$callbacks = { before: function(){}, beforeEach: function(){}, after: function(){}, afterEach: function(){} }; callbacks = callbacks || {}; this.setCallbacks({ before: callbacks.before, beforeEach: callbacks.beforeEach, after: callbacks.after, afterEach: callbacks.afterEach }); this.$testCount = 0; this.$doneCount = 0; this.$passes = 0; this.$failures = 0; this.$scaffolds = { before: function(){}, beforeEach: function(){}, after: function(){}, afterEach: function(){} }; }; Suite.setMatcher = function(name, fn){ Case.setMatcher(name, fn); }; Suite.prototype.setCallback = function(type, fn){ if (fn === undefined || !(fn instanceof Function)) throw new TypeError('Suite.setCallback requires a function as its second argument.'); this.$callbacks[type] = fn; return this; }; Suite.prototype.setCallbacks = function(keys){ for (var key in keys){ if (keys[key] !== undefined && keys[key] instanceof Function) this.setCallback(key, keys[key]); } return this; }; Suite.prototype.done = function(){ return !(this.$testCount - this.$doneCount); }; Suite.prototype.count = function(){ return this.$testCount; }; Suite.prototype.results = function(){ if (!this.done()) return {}; return { suite: this.name, allPassed: (this.$failures === 0), tests: { passes: this.$passes, failures: this.$failures, total: this.$testCount }, results: this.$results }; }; var callNext = function(){ var current = this.$tests.shift(); if (current){ this.$scaffolds.beforeEach.call(this.$context); current.run(); } else { this.$scaffolds.after.call(this.$context); this.$callbacks.after.call(null, this.name, (this.$failures === 0), this.results()); } }; var itCallback = function(){ var self = this; return function(results, success){ self.$doneCount++; self.$results.push(results); self[success ? '$passes' : '$failures']++; self.$scaffolds.afterEach.call(self.$context); self.$callbacks.afterEach.call(null, self.name, results.description, results); callNext.call(self); }; }; Suite.prototype.$it = function(desc, fn){ var self = this; this.$testCount++; var test = new Case(desc, fn, this.$context, { before: function(desc, count){ self.$callbacks.beforeEach.call(null, self.name, desc, count); }, after: itCallback.call(this) }, this.$argCheck); this.$tests.push(test); }; Suite.prototype.$setup = function(type, fn){ if (fn !== undefined && fn instanceof Function) this.$scaffolds[type] = fn; return this; }; Suite.prototype.prepare = function(){ var self = this; this.$body.call(null, function(){ return self.$it.apply(self, Array.prototype.slice.call(arguments)); }, function(){ return self.$setup.apply(self, Array.prototype.slice.call(arguments)); }); this.$prepared = true; this.$callbacks.before.call(null, this.name, this.$testCount); return this; }; Suite.prototype.run = function(){ if (!this.$prepared) this.prepare(); this.$scaffolds.before.call(this.$context); callNext.call(this); return this; }; exports.Suite = Suite; })();