spectacular
Version:
Advanced BDD framework for CoffeeScript and JavaScript
1,806 lines (1,599 loc) • 145 kB
JavaScript
// Generated by CoffeeScript 1.6.3
var BADGE_MAP, CHAR_MAP, COLOR_MAP, LINE_RE, URI_RE, exports, isCommonJS, k, spectacular, utils, v, _ref,
__slice = [].slice,
__indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; },
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; },
__bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
if (Object.getPropertyDescriptor == null) {
Object.getPropertyDescriptor = function(o, name) {
var descriptor, proto;
proto = o;
descriptor = void 0;
while (proto && !(descriptor = Object.getOwnPropertyDescriptor(proto, name))) {
proto = (typeof Object.getPrototypeOf === "function" ? Object.getPrototypeOf(proto) : void 0) || proto.__proto__;
}
return descriptor;
};
}
if (Function.prototype.include == null) {
Function.prototype.include = function() {
var excl, excluded, k, mixin, mixins, v, _i, _len, _ref;
mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
excluded = ['constructor', 'excluded'];
for (_i = 0, _len = mixins.length; _i < _len; _i++) {
mixin = mixins[_i];
excl = excluded.concat();
if (mixin.prototype.excluded != null) {
excl = excl.concat(mixin.prototype.excluded);
}
_ref = mixin.prototype;
for (k in _ref) {
v = _ref[k];
if (__indexOf.call(excl, k) < 0) {
this.prototype[k] = v;
}
}
if (typeof mixin.included === "function") {
mixin.included(this);
}
}
return this;
};
}
if (Function.prototype.extend == null) {
Function.prototype.extend = function() {
var excl, excluded, k, mixin, mixins, v, _i, _len;
mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
excluded = ['extended', 'excluded', 'included'];
for (_i = 0, _len = mixins.length; _i < _len; _i++) {
mixin = mixins[_i];
excl = excluded.concat();
if (mixin.excluded != null) {
excl = excl.concat(mixin.excluded);
}
for (k in mixin) {
v = mixin[k];
if (__indexOf.call(excl, k) < 0) {
this[k] = v;
}
}
if (typeof mixin.extended === "function") {
mixin.extended(this);
}
}
return this;
};
}
if (Function.prototype.concern == null) {
Function.prototype.concern = function() {
var mixins;
mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
this.include.apply(this, mixins);
return this.extend.apply(this, mixins);
};
}
if (Function.prototype.getter == null) {
Function.prototype.getter = function(name, block) {
var oldDescriptor, set;
oldDescriptor = Object.getPropertyDescriptor(this.prototype, name);
if (oldDescriptor != null) {
set = oldDescriptor.set;
}
Object.defineProperty(this.prototype, name, {
get: block,
set: set,
configurable: true,
enumerable: true
});
return this;
};
}
if (Function.prototype.setter == null) {
Function.prototype.setter = function(name, block) {
var get, oldDescriptor;
oldDescriptor = Object.getPropertyDescriptor(this.prototype, name);
if (oldDescriptor != null) {
get = oldDescriptor.get;
}
Object.defineProperty(this.prototype, name, {
set: block,
get: get,
configurable: true,
enumerable: true
});
return this;
};
}
if (Function.prototype.accessor == null) {
Function.prototype.accessor = function(name, options) {
return Object.defineProperty(this.prototype, name, {
get: options.get,
set: options.set,
configurable: true,
enumerable: true
});
};
}
if (Function.prototype.signature == null) {
Function.prototype.signature = function() {
var re, _ref;
re = /^function(\s+[a-zA-Z_][a-zA-Z0-9_]*)*\s*\(([^\)]+)\)/;
return ((_ref = re.exec(this.toString())) != null ? _ref[2].split(/\s*,\s*/) : void 0) || [];
};
}
isCommonJS = typeof window === "undefined";
if (isCommonJS) {
exports = exports || {};
} else {
exports = window;
}
exports.spectacular = exports.spectacular || {};
spectacular = exports.spectacular;
spectacular.version = '1.6.0';
spectacular.global = (function() {
if (typeof window !== 'undefined') {
return window;
}
if (typeof global !== 'undefined') {
return global;
}
return {};
})();
spectacular.deprecated = function(message) {
var caller, deprecatedMethodCallerFile, deprecatedMethodCallerName, e, parseLine, s, _ref;
parseLine = function(line) {
var f, m, o, _ref, _ref1, _ref2, _ref3;
if (line.indexOf('@') > 0) {
if (line.indexOf('</') > 0) {
_ref = /<\/([^@]+)@(.)+$/.exec(line), m = _ref[0], o = _ref[1], f = _ref[2];
} else {
_ref1 = /@(.)+$/.exec(line), m = _ref1[0], f = _ref1[1];
}
} else {
if (line.indexOf('(') > 0) {
_ref2 = /at\s+([^\s]+)\s*\(([^\)])+/.exec(line), m = _ref2[0], o = _ref2[1], f = _ref2[2];
} else {
_ref3 = /at\s+([^\s]+)/.exec(line), m = _ref3[0], f = _ref3[1];
}
}
return [o, f];
};
e = new Error();
caller = '';
if (e.stack != null) {
s = e.stack.split('\n');
_ref = parseLine(s[3]), deprecatedMethodCallerName = _ref[0], deprecatedMethodCallerFile = _ref[1];
caller = deprecatedMethodCallerName ? " (called from " + deprecatedMethodCallerName + " at " + deprecatedMethodCallerFile + ")" : "(called from " + deprecatedMethodCallerFile + ")";
}
return console.log("DEPRECATION WARNING: " + message + caller);
};
spectacular.deprecated._name = 'deprecated';
spectacular.nextTick = (typeof process !== "undefined" && process !== null ? process.setImmediate : void 0) || (typeof process !== "undefined" && process !== null ? process.nextTick : void 0) || (typeof window !== "undefined" && window !== null ? window.setImmediate : void 0) || (typeof window !== "undefined" && window !== null ? window.nextTick : void 0) || function(callback) {
return setTimeout(callback, 0);
};
utils = spectacular.utils || (spectacular.utils = {});
spectacular.utils.squeeze = function(s) {
return s.replace(/\s+/g, ' ');
};
spectacular.utils.strip = function(s) {
return s.replace(/^\s+|\s+$/g, '');
};
spectacular.utils.capitalize = function(s) {
return s.replace(/^(\w)/, function(m, c) {
return c.toUpperCase();
});
};
spectacular.utils.underscore = function(s) {
return s.replace(/([a-z])([A-Z])/g, "$1_$2").split(/[-/]|\s/g).join("_").toLowerCase();
};
spectacular.utils.camelize = function(s) {
var a, w, _i, _len;
a = s.toLowerCase().split(/[_\s-]/);
s = a.shift();
for (_i = 0, _len = a.length; _i < _len; _i++) {
w = a[_i];
s = "" + s + (utils.capitalize(w));
}
return s;
};
spectacular.utils.snakify = function(o) {
var descriptor, k, v, _results;
_results = [];
for (k in o) {
v = o[k];
descriptor = Object.getOwnPropertyDescriptor(o, k);
if (descriptor != null) {
_results.push(Object.defineProperty(o, utils.underscore(k), descriptor));
} else {
_results.push(o[utils.underscore(k)] = v);
}
}
return _results;
};
spectacular.utils.keys = function(o) {
var k, _results;
_results = [];
for (k in o) {
_results.push(k);
}
return _results;
};
spectacular.utils.isArray = function(o) {
return Object.prototype.toString.call(o) === '[object Array]';
};
spectacular.utils.literalEnumeration = function(array) {
var last, result;
if (array.length > 1) {
last = array.pop();
result = array.join(', ');
result += " and " + last;
} else {
result = array.toString();
}
return result;
};
spectacular.utils.fill = function(l, s) {
var o;
if (l == null) {
l = 4;
}
if (s == null) {
s = ' ';
}
o = '';
while (o.length < l) {
o = "" + o + s;
}
return o;
};
spectacular.utils.uniq = function(arr) {
var newArr, v, _i, _len;
newArr = [];
for (_i = 0, _len = arr.length; _i < _len; _i++) {
v = arr[_i];
if (__indexOf.call(newArr, v) < 0) {
newArr.push(v);
}
}
return newArr;
};
spectacular.utils.escapeDiff = function(s) {
return utils.escape(s.replace(/<del>/g, '[[del]]').replace(/<\/del>/g, '[[/del]]').replace(/<ins>/g, '[[ins]]').replace(/<\/ins>/g, '[[/ins]]')).replace(/\[\[del\]\]/g, '<del>').replace(/\[\[\/del\]\]/g, '</del>').replace(/\[\[ins\]\]/g, '<ins>').replace(/\[\[\/ins\]\]/g, '</ins>');
};
spectacular.utils.escape = function(s) {
var n;
n = s;
n = n.replace(/&/g, '&');
n = n.replace(/</g, '<');
n = n.replace(/>/g, '>');
n = n.replace(/"/g, '"');
return n;
};
spectacular.utils.unescape = function(s) {
var n;
n = s;
n = n.replace(/&/g, '&');
n = n.replace(/</g, '<');
n = n.replace(/>/g, '>');
n = n.replace(/"/g, '"');
return n;
};
spectacular.utils.indent = function(string, ind) {
var i, s, _i, _ref;
if (ind == null) {
ind = 4;
}
s = '';
for (i = _i = 0, _ref = ind - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
s = "" + s + " ";
}
return "" + s + (string.replace(/\n/g, "\n" + s));
};
spectacular.utils.padRight = function(string, pad) {
if (pad == null) {
pad = 4;
}
string = string.toString();
while (string.length < pad) {
string = " " + string;
}
return string;
};
spectacular.utils.toggle = function(value, c1, c2) {
if (value) {
return c2;
} else {
return c1;
}
};
spectacular.utils.TAGS = isCommonJS ? {
diffStart: '',
diffEnd: '',
delStart: '\x1B[31m',
delEnd: '\x1B[39m',
insStart: '\x1B[32m',
insEnd: '\x1B[39m',
space: ''
} : {
diffStart: '<span class="diff">',
diffEnd: '</span>',
delStart: '<del>',
delEnd: '</del>',
insStart: '<ins>',
insEnd: '</ins>',
space: ''
};
spectacular.utils.ins = function(str) {
return utils.TAGS.insStart + str + utils.TAGS.insEnd;
};
spectacular.utils.del = function(str) {
return utils.TAGS.delStart + str + utils.TAGS.delEnd;
};
spectacular.utils.descOfNode = function(actual) {
if (actual != null) {
if (actual.length != null) {
return utils.inspect(Array.prototype.map.call(actual, function(e) {
return e.outerHTML;
}));
} else {
return utils.inspect(actual.outerHTML);
}
} else {
return actual;
}
};
spectacular.utils.diff = function(o, n) {
var i, ns, os;
ns = new Object();
os = new Object();
i = 0;
while (i < n.length) {
if ((ns[n[i]] == null) || typeof ns[n[i]] !== 'object') {
ns[n[i]] = {
rows: new Array(),
o: null
};
}
ns[n[i]].rows.push(i);
i++;
}
i = 0;
while (i < o.length) {
if ((os[o[i]] == null) || typeof os[n[i]] !== 'object') {
os[o[i]] = {
rows: new Array(),
n: null
};
}
os[o[i]].rows.push(i);
i++;
}
for (i in ns) {
if (ns[i].rows.length === 1 && typeof os[i] !== "undefined" && os[i].rows.length === 1) {
n[ns[i].rows[0]] = {
text: n[ns[i].rows[0]],
row: os[i].rows[0]
};
o[os[i].rows[0]] = {
text: o[os[i].rows[0]],
row: ns[i].rows[0]
};
}
}
i = 0;
while (i < n.length - 1) {
if ((n[i].text != null) && (n[i + 1].text == null) && n[i].row + 1 < o.length && (o[n[i].row + 1].text == null) && n[i + 1] === o[n[i].row + 1]) {
n[i + 1] = {
text: n[i + 1],
row: n[i].row + 1
};
o[n[i].row + 1] = {
text: o[n[i].row + 1],
row: i + 1
};
}
i++;
}
i = n.length - 1;
while (i > 0) {
if ((n[i].text != null) && (n[i - 1].text == null) && n[i].row > 0 && (o[n[i].row - 1].text == null) && n[i - 1] === o[n[i].row - 1]) {
n[i - 1] = {
text: n[i - 1],
row: n[i].row - 1
};
o[n[i].row - 1] = {
text: o[n[i].row - 1],
row: i - 1
};
}
i--;
}
return {
o: o,
n: n
};
};
spectacular.utils.stringDiff = function(o, n) {
var i, nSpace, oSpace, out, pre, str;
if ((n == null) || n.length === 0) {
return utils.del(o);
}
if ((o == null) || o.length === 0) {
return utils.ins(n);
}
o = String(o).replace(/\s+$/, "");
n = String(n).replace(/\s+$/, "");
out = utils.diff((o === "" ? [] : o.split(/\s+/)), (n === "" ? [] : n.split(/\s+/)));
str = "";
oSpace = o.match(/\s+/g);
if (oSpace == null) {
oSpace = [utils.TAGS.space];
} else {
oSpace.push(utils.TAGS.space);
}
nSpace = n.match(/\s+/g);
if (nSpace == null) {
nSpace = [utils.TAGS.space];
} else {
nSpace.push(utils.TAGS.space);
}
if (out.n.length === 0) {
i = 0;
while (i < out.o.length) {
str += utils.del(utils.escape(out.o[i]) + oSpace[i]);
i++;
}
} else {
if (out.n[0].text == null) {
n = 0;
while (n < out.o.length && (out.o[n].text == null)) {
str += utils.del(utils.escape(out.o[n]) + oSpace[n]);
n++;
}
}
i = 0;
while (i < out.n.length) {
if (out.n[i].text == null) {
str += utils.ins(utils.escape(out.n[i]) + nSpace[i]);
} else {
pre = "";
n = out.n[i].row + 1;
while (n < out.o.length && (out.o[n].text == null)) {
pre += utils.del(utils.escape(out.o[n]) + oSpace[n]);
n++;
}
str += "" + out.n[i].text + nSpace[i] + pre;
}
i++;
}
}
return str;
};
spectacular.utils.inspect = function(obj, depth, lookup) {
var ind, k, v;
if (depth == null) {
depth = 1;
}
if (lookup == null) {
lookup = [];
}
switch (typeof obj) {
case 'string':
return "'" + obj + "'";
case 'number':
case 'boolean':
return "" + obj;
case 'object':
if (obj == null) {
return 'null';
}
if (__indexOf.call(lookup, obj) >= 0) {
return '[circular]';
}
lookup.push(obj);
ind = utils.fill(depth * 2);
if (utils.isArray(obj)) {
if (obj.length === 0) {
return '[]';
}
return "[\n" + (obj.map(function(o) {
return ind + utils.inspect(o, depth + 1, lookup);
}).join(',\n')) + "\n" + ind.slice(0, -2) + "]";
} else {
if (utils.keys(obj).length === 0) {
return '{}';
}
return "{\n" + (((function() {
var _results;
_results = [];
for (k in obj) {
v = obj[k];
if (obj.hasOwnProperty(k)) {
_results.push("" + ind + k + ": " + (utils.inspect(v, depth + 1, lookup)));
}
}
return _results;
})()).join(',\n')) + "\n" + ind.slice(0, -2) + "}";
}
break;
case 'function':
if (obj.name) {
return obj.name;
} else if (obj._name) {
return obj._name;
} else {
return obj.toString();
}
break;
default:
return 'undefined';
}
};
spectacular.utils.objectDiff = function(left, right, depth) {
var a, allKeys, i, ind, k, key, l, p, prevInd, s, typeLeft, typeRight;
if (depth == null) {
depth = 1;
}
typeLeft = typeof left;
typeRight = typeof right;
if (typeLeft !== typeRight) {
s = '';
if (left != null) {
s += utils.del(utils.inspect(left, depth));
}
if (right != null) {
s += utils.ins(utils.inspect(right, depth));
}
return s;
}
switch (typeLeft) {
case 'string':
return utils.inspect(utils.stringDiff(left, right));
case 'number':
case 'boolean':
return utils.stringDiff(left.toString(), right.toString());
case 'object':
if (utils.isArray(left) !== utils.isArray(right)) {
return utils.del(utils.inspect(left, depth)) + utils.ins(utils.inspect(right, depth));
}
ind = utils.fill(depth * 2);
prevInd = utils.fill((depth - 1) * 2);
if (utils.isArray(left)) {
l = Math.max(left.length, right.length);
s = '[';
a = (function() {
var _i, _ref, _results;
_results = [];
for (i = _i = 0, _ref = l - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; i = 0 <= _ref ? ++_i : --_i) {
_results.push('\n' + ind + utils.objectDiff(left[i], right[i], depth + 1));
}
return _results;
})();
return s += a.join(',') + ("\n" + prevInd + "]");
} else {
allKeys = utils.uniq(utils.keys(left).concat(utils.keys(right)));
s = "{";
a = (function() {
var _i, _len, _results;
_results = [];
for (_i = 0, _len = allKeys.length; _i < _len; _i++) {
k = allKeys[_i];
key = k + ': ';
p = '';
if (!right[k]) {
p = utils.del("" + key + left[k]);
} else if (!left[k]) {
p = utils.ins("" + key + right[k]);
} else {
p = key + utils.objectDiff(left[k], right[k], depth + 1);
}
_results.push('\n' + ind + p);
}
return _results;
})();
return s += a.join(',') + ("\n" + prevInd + "}");
}
}
};
spectacular.utils.compare = function(actual, value, diff, noMessage) {
var i, k, v, _i, _len;
if (noMessage == null) {
noMessage = false;
}
switch (typeof value) {
case 'object':
if (utils.isArray(actual)) {
if (!noMessage) {
diff.diff = utils.TAGS.diffStart + ("" + diff.diff + "\n\n" + (utils.objectDiff(actual, value))) + utils.TAGS.diffEnd;
}
if (actual.length !== value.length) {
return false;
}
for (i = _i = 0, _len = value.length; _i < _len; i = ++_i) {
v = value[i];
if (!utils.compare(actual[i], v, diff, true)) {
return false;
}
}
return true;
} else {
if (!noMessage) {
diff.diff = utils.TAGS.diffStart + ("" + diff.diff + "\n\n" + (utils.objectDiff(actual, value))) + utils.TAGS.diffEnd;
}
if (utils.keys(actual).length !== utils.keys(value).length) {
return false;
}
for (k in value) {
v = value[k];
if (!utils.compare(actual[k], v, diff, true)) {
return false;
}
}
return true;
}
break;
case 'string':
if (!noMessage) {
diff.diff = utils.TAGS.diffStart + ("" + diff.diff + "\n\n'" + (utils.stringDiff(actual, value)) + "'") + utils.TAGS.diffEnd;
}
return actual === value;
default:
return actual === value;
}
};
spectacular.utils.findStateMethodOrProperty = function(obj, state) {
var camelizedVersion, snakedVersion;
camelizedVersion = "is" + (utils.capitalize(state));
snakedVersion = "is_" + state;
if (obj[state] != null) {
return state;
} else if (obj[camelizedVersion] != null) {
return camelizedVersion;
} else if (obj[snakedVersion] != null) {
return snakedVersion;
} else {
return null;
}
};
for (k in utils) {
v = utils[k];
v._name = k;
}
spectacular.utils.colorize = function(str, color, colorsEnabled) {
if (colorsEnabled == null) {
colorsEnabled = false;
}
if ((str != null) && colorsEnabled && (str != null ? str[color] : void 0)) {
return str[color];
} else {
return str;
}
};
URI_RE = '((http:\\/\\/)?.*\\.(js|coffee))(\\?[^:]*)*';
LINE_RE = ':(\\d+)(:(\\d+))*';
spectacular.errors = {};
spectacular.errors.GeckoParser = (function() {
function GeckoParser() {}
GeckoParser.prototype.match = function(stack) {
return /@/g.test(stack);
};
GeckoParser.prototype.filter = function(line) {
return /@/.test(line);
};
GeckoParser.prototype.details = function(line) {
var c, column, e, file, h, match, method, p, q, re, _ref;
re = RegExp("\\s*([^\\s]*)(@)" + URI_RE + LINE_RE);
if (re.test(line)) {
_ref = re.exec(line), match = _ref[0], method = _ref[1], p = _ref[2], file = _ref[3], h = _ref[4], e = _ref[5], q = _ref[6], line = _ref[7], c = _ref[8], column = _ref[9];
} else {
return {
"native": true
};
}
return {
file: file,
line: line,
column: column,
method: method
};
};
return GeckoParser;
})();
spectacular.errors.V8Parser = (function() {
function V8Parser() {}
V8Parser.prototype.match = function(stack) {
return /\s+at\s+/g.test(stack);
};
V8Parser.prototype.filter = function(line) {
return /\s+at\s+/.test(line);
};
V8Parser.prototype.details = function(line) {
var c, column, e, file, h, match, method, p, q, re, _ref;
re = RegExp("at\\s*(([^\\s]*)\\s*\\(|\\()*" + URI_RE + LINE_RE);
if (re.test(line)) {
_ref = re.exec(line), match = _ref[0], p = _ref[1], method = _ref[2], file = _ref[3], h = _ref[4], e = _ref[5], q = _ref[6], line = _ref[7], c = _ref[8], column = _ref[9];
} else {
return {
"native": true
};
}
return {
file: file,
line: line,
column: column,
method: method,
params: q
};
};
return V8Parser;
})();
spectacular.errors.ErrorParser = (function() {
ErrorParser.supportedFormats = [new spectacular.errors.V8Parser, new spectacular.errors.GeckoParser];
function ErrorParser(stack) {
this.stack = stack;
this.detectFormat();
this.splitLines();
}
ErrorParser.prototype.splitLines = function() {
this.lines = this.stack.split('\n');
if (this.format != null) {
this.lines = this.lines.filter(this.format.filter);
}
return this.size = this.lines.length;
};
ErrorParser.prototype.detectFormat = function() {
var format, _i, _len, _ref, _results;
_ref = ErrorParser.supportedFormats;
_results = [];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
format = _ref[_i];
if (format.match(this.stack)) {
_results.push(this.format = format);
}
}
return _results;
};
ErrorParser.prototype.find = function(query) {
return this.lines.filter(function(line) {
return RegExp("" + query).test(line);
});
};
ErrorParser.prototype.details = function(line) {
var _ref;
return (_ref = this.format) != null ? _ref.details(line) : void 0;
};
return ErrorParser;
})();
spectacular.HasAncestors = (function() {
function HasAncestors() {}
HasAncestors.included = function(ctor) {
ctor.getter('ancestors', function() {
var ancestors, parent;
ancestors = [];
parent = this.parent;
while (parent) {
ancestors.push(parent);
parent = parent.parent;
}
return ancestors;
});
return ctor.ancestorsScope = function(name, block) {
return this.getter(name, function() {
return this.ancestors.filter(block);
});
};
};
HasAncestors.prototype.nthAncestor = function(level) {
var n, parent, _i;
if (level < 1) {
level = 1;
}
parent = this;
n = 0;
for (n = _i = 0; 0 <= level ? _i <= level : _i >= level; n = 0 <= level ? ++_i : --_i) {
parent = parent.parent;
}
return parent;
};
return HasAncestors;
})();
spectacular.Globalizable = (function() {
function Globalizable() {}
Globalizable.unglobalizable = ['globalize', 'unglobalize', 'keepContext', 'globalizeMember', 'unglobalizeMember', 'globalizable', 'globalized', 'alternate', 'previous'];
Globalizable.prototype.keepContext = true;
Globalizable.prototype.globalize = function() {
var _this = this;
this.previous || (this.previous = {});
this.globalizable.forEach(function(k) {
if (__indexOf.call(_this.constructor.unglobalizable || Globalizable.unglobalizable, k) < 0) {
return _this.globalizeMember(k, _this[k]);
}
});
return this.globalized = true;
};
Globalizable.prototype.unglobalize = function() {
var _this = this;
this.globalizable.forEach(function(k) {
if (__indexOf.call(_this.constructor.unglobalizable || Globalizable.unglobalizable, k) < 0) {
return _this.unglobalizeMember(k, _this[k]);
}
});
return this.globalized = false;
};
Globalizable.prototype.globalizeMember = function(key, value, alternate) {
var alt, proxy, self, _global;
if (alternate == null) {
alternate = true;
}
_global = spectacular.global;
if (_global[key] != null) {
this.previous[key] = _global[key];
}
self = this;
if (typeof value === 'function') {
if (value._name == null) {
value._name = key;
}
if (this.keepContext) {
proxy = function() {
return value.apply(self, arguments);
};
proxy._name = key;
_global[key] = proxy;
} else {
_global[key] = value;
}
} else {
_global[key] = value;
}
if (alternate) {
alt = this.alternate(key);
if (alt !== key) {
return this.globalizeMember(alt, value, false);
}
}
};
Globalizable.prototype.unglobalizeMember = function(key, value, alternate) {
var alt, _global;
if (alternate == null) {
alternate = true;
}
_global = spectacular.global;
if (this.previous[key] != null) {
_global[key] = this.previous[key];
} else {
delete _global[key];
}
if (alternate) {
alt = this.alternate(key);
if (alt !== key) {
return this.unglobalizeMember(alt, value, false);
}
}
};
Globalizable.prototype.alternate = function(key) {
if (key.indexOf('_') === -1) {
return utils.underscore(key);
} else {
return utils.camelize(key);
}
};
return Globalizable;
})();
spectacular.Hookable = (function() {
function Hookable() {}
Hookable.hook = function(name) {
var capitalizedName;
capitalizedName = utils.capitalize(name);
this.mergeUp("" + name + "Hooks");
return this.accessor("own" + capitalizedName + "Hooks", {
get: function() {
var _name;
return this[_name = "__own" + capitalizedName + "Hooks"] || (this[_name] = []);
},
set: function(v) {
return this["__own" + capitalizedName + "Hooks"] = v;
}
});
};
Hookable.prototype.registerHook = function(name, block) {
var capitalizedName;
capitalizedName = utils.capitalize(name);
return this["own" + capitalizedName + "Hooks"].push(block);
};
return Hookable;
})();
spectacular.GlobalizableObject = (function() {
GlobalizableObject.include(spectacular.Globalizable);
GlobalizableObject.unglobalizable = spectacular.Globalizable.unglobalizable.concat('set');
function GlobalizableObject() {
var __globalizable;
__globalizable = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
this.__globalizable = __globalizable;
}
Object.defineProperty(GlobalizableObject.prototype, 'globalizable', {
configurable: true,
get: function() {
if (this.__globalizable.length > 0) {
return this.__globalizable;
} else {
return utils.keys(this);
}
}
});
GlobalizableObject.prototype.set = function(property, value) {
this[property] = value;
if (this.globalized) {
return this.globalizeMember(property, value);
}
};
return GlobalizableObject;
})();
spectacular.HasCollection = function(plural, singular) {
var ConcreteHasCollection, capitalizedPlural, capitalizedSingular, mixin;
capitalizedSingular = utils.capitalize(singular);
capitalizedPlural = utils.capitalize(plural);
mixin = ConcreteHasCollection = (function() {
function ConcreteHasCollection() {}
ConcreteHasCollection.included = function(ctor) {
return ctor["" + plural + "Scope"] = function(name, block) {
return ctor.getter(name, function() {
return this[plural].filter(block);
});
};
};
return ConcreteHasCollection;
})();
mixin.prototype["add" + capitalizedSingular] = function() {
var item, items, _i, _len, _results;
items = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
_results = [];
for (_i = 0, _len = items.length; _i < _len; _i++) {
item = items[_i];
if (__indexOf.call(this[plural], item) < 0) {
_results.push(this[plural].push(item));
}
}
return _results;
};
mixin.prototype["remove" + capitalizedSingular] = function() {
var item, items, newArray, _i, _len, _ref;
items = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
newArray = [];
_ref = this[plural];
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
item = _ref[_i];
if (__indexOf.call(items, item) < 0) {
newArray.push(item);
}
}
return this[plural] = newArray;
};
mixin.prototype["" + singular + "At"] = function(index) {
return this[plural][index];
};
mixin.prototype["find" + capitalizedSingular] = mixin.prototype["indexOf" + capitalizedSingular] = function(item) {
return this[plural].indexOf(item);
};
mixin.prototype["has" + capitalizedSingular] = mixin.prototype["contains" + capitalizedSingular] = function(item) {
return this[plural].indexOf(item) !== -1;
};
mixin.prototype["" + plural + "Length"] = mixin.prototype["" + plural + "Size"] = mixin.prototype["" + plural + "Count"] = function() {
return this[plural].length;
};
return mixin;
};
spectacular.HasNestedCollection = function(name, options) {
var ConcreteHasNestedCollection, mixin, through;
if (options == null) {
options = {};
}
through = options.through;
if (through == null) {
throw new Error('missing through option');
}
mixin = ConcreteHasNestedCollection = (function() {
function ConcreteHasNestedCollection() {}
ConcreteHasNestedCollection.included = function(ctor) {
ctor["" + name + "Scope"] = function(scopeName, block) {
return ctor.getter(scopeName, function() {
return this[name].filter(block);
});
};
return ctor.getter(name, function() {
var items;
items = [];
this[through].forEach(function(item) {
items.push(item);
if (item[name] != null) {
return items = items.concat(item[name]);
}
});
return items;
});
};
return ConcreteHasNestedCollection;
})();
return mixin;
};
spectacular.AncestorsProperties = (function() {
function AncestorsProperties() {}
AncestorsProperties.followUp = function(property) {
var capitalizedProperty, privateProperty;
capitalizedProperty = utils.capitalize(property);
privateProperty = "own" + capitalizedProperty;
return this.accessor(property, {
get: function() {
var _ref;
return this[privateProperty] || ((_ref = this.parent) != null ? _ref[property] : void 0);
},
set: function(value) {
return this[privateProperty] = value;
}
});
};
AncestorsProperties.mergeUp = function(property) {
var capitalizedProperty, privateProperty;
capitalizedProperty = utils.capitalize(property);
privateProperty = "own" + capitalizedProperty;
return this.accessor(property, {
get: function() {
var a;
a = this[privateProperty];
if (this.parent != null) {
a = this.parent[property].concat(a);
}
return a;
},
set: function(value) {
return this[privateProperty] = value;
}
});
};
return AncestorsProperties;
})();
spectacular.Describable = (function() {
function Describable() {}
Describable.included = function(ctor) {
return ctor.getter('description', function() {
var space, _ref;
if (((_ref = this.parent) != null ? _ref.description : void 0) != null) {
space = '';
if (!this.noSpaceBeforeDescription) {
space = ' ';
}
return "" + this.parent.description + space + this.ownDescription;
} else {
return this.ownDescription;
}
});
};
return Describable;
})();
spectacular.Event = (function() {
function Event(name, target) {
this.name = name;
this.target = target;
}
return Event;
})();
spectacular.EventDispatcher = (function() {
function EventDispatcher() {}
EventDispatcher.prototype.on = function(event, callback) {
var _base;
this.listeners || (this.listeners = {});
(_base = this.listeners)[event] || (_base[event] = []);
if (__indexOf.call(this.listeners[event], callback) < 0) {
return this.listeners[event].push(callback);
}
};
EventDispatcher.prototype.off = function(event, callback) {
var _ref;
if ((((_ref = this.listeners) != null ? _ref[event] : void 0) != null) && __indexOf.call(this.listeners[event], callback) >= 0) {
return this.listeners[event].splice(this.listeners[event].indexOf(callback), 1);
}
};
EventDispatcher.prototype.hasListener = function(event) {
var _ref;
return (((_ref = this.listeners) != null ? _ref[event] : void 0) != null) && this.listeners[event].length > 0;
};
EventDispatcher.prototype.dispatch = function(event) {
var _ref, _ref1;
return (_ref = this.listeners) != null ? (_ref1 = _ref[event.name]) != null ? _ref1.forEach(function(listener) {
return listener(event);
}) : void 0 : void 0;
};
return EventDispatcher;
})();
spectacular.factories || (spectacular.factories = new spectacular.GlobalizableObject('build', 'create', 'factory', 'factoryMixin'));
spectacular.factories.keepContext = false;
spectacular.factories.buildMethodsCache = {};
spectacular.factories.build = function(ctor, args) {
var argumentsSignature, comma, f, n;
if (args == null) {
args = [];
}
f = spectacular.factories.buildMethodsCache[args.length] != null ? spectacular.factories.buildMethodsCache[args.length] : (argumentsSignature = '', comma = '', args.length > 0 ? (argumentsSignature = ((function() {
var _i, _ref, _results;
_results = [];
for (n = _i = 0, _ref = args.length - 1; 0 <= _ref ? _i <= _ref : _i >= _ref; n = 0 <= _ref ? ++_i : --_i) {
_results.push("arg" + n);
}
return _results;
})()).join(','), comma = ',') : void 0, spectacular.factories.buildMethodsCache[args.length] = new Function("ctor" + comma + argumentsSignature, "return new ctor(" + argumentsSignature + ");"));
return f.apply(null, [ctor].concat(args));
};
spectacular.factories.Set = (function() {
function Set(property, value) {
this.property = property;
this.value = value;
}
Set.prototype.apply = function(instance) {
if (typeof this.value === 'function') {
return instance[this.property] = this.value();
} else {
return instance[this.property] = this.value;
}
};
return Set;
})();
spectacular.factories.Trait = (function() {
Trait.concern(spectacular.Hookable);
Trait.include(spectacular.Globalizable);
Trait.include(spectacular.HasAncestors);
Trait.extend(spectacular.AncestorsProperties);
Trait.followUp('arguments');
Trait.followUp('buildBlock');
Trait.hook('build');
Trait.prototype.globalizable = 'set createWith build after'.split(/\s+/g);
function Trait(name) {
this.name = name;
this.previous = {};
this.setters = [];
}
Trait.prototype.set = function(property, value) {
return this.setters.push(new spectacular.factories.Set(property, value));
};
Trait.prototype.build = function(ownBuildBlock) {
this.ownBuildBlock = ownBuildBlock;
};
Trait.prototype.createWith = function() {
var ownArguments;
ownArguments = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
this.ownArguments = ownArguments;
};
Trait.prototype.after = function(hook, block) {
return this.registerHook(hook, block);
};
Trait.prototype.applySet = function(instance) {
return this.setters.forEach(function(setter) {
return setter.apply(instance);
});
};
return Trait;
})();
spectacular.factories.Factory = (function(_super) {
__extends(Factory, _super);
Factory.prototype.globalizable = 'set trait createWith build include after'.split(/\s+/g);
function Factory(name, _class) {
this["class"] = _class;
Factory.__super__.constructor.call(this, name);
this.traits = {};
}
Factory.prototype.trait = function(name, block) {
var trait, _base;
trait = (_base = this.traits)[name] || (_base[name] = new spectacular.factories.Trait(name));
trait.globalize();
block.call(trait);
return trait.unglobalize();
};
Factory.prototype.buildInstance = function(traits, options) {
var args, hook, hooks, instance, trait, _i, _j, _len, _len1;
if (options == null) {
options = {};
}
args = this.getConstructorArguments(traits);
instance = this.parent != null ? this.parent.instanciate(args, traits) : this.instanciate(args, traits);
this.applySet(instance);
for (_i = 0, _len = traits.length; _i < _len; _i++) {
trait = traits[_i];
this.findTrait(trait).applySet(instance);
}
for (k in options) {
v = options[k];
instance[k] = v;
}
hooks = this.fromTraitAndThis('buildHooks', traits);
for (_j = 0, _len1 = hooks.length; _j < _len1; _j++) {
hook = hooks[_j];
hook.call(instance, instance);
}
return instance;
};
Factory.prototype.instanciate = function(args, traits) {
var buildBlock;
buildBlock = this.fromTraitOrThis('buildBlock', traits);
if (buildBlock != null) {
return buildBlock.apply(this, [this["class"]].concat(args));
} else {
return build(this["class"], args);
}
};
Factory.prototype.fromTraitOrThis = function(property, traits) {
var trait, traitValue, value, _i, _len;
value = this[property];
for (_i = 0, _len = traits.length; _i < _len; _i++) {
trait = traits[_i];
traitValue = this.findTrait(trait)[property];
if (traitValue != null) {
value = traitValue;
}
}
return value;
};
Factory.prototype.fromTraitAndThis = function(property, traits) {
var trait, traitValue, value, _i, _len;
value = this[property];
for (_i = 0, _len = traits.length; _i < _len; _i++) {
trait = traits[_i];
traitValue = this.findTrait(trait)[property];
if (traitValue != null) {
value = value.concat(traitValue);
}
}
return value;
};
Factory.prototype.include = function() {
var mixin, mixinName, mixins, _i, _len, _results;
mixins = 1 <= arguments.length ? __slice.call(arguments, 0) : [];
_results = [];
for (_i = 0, _len = mixins.length; _i < _len; _i++) {
mixinName = mixins[_i];
mixin = spectacular.factories.mixins[mixinName];
if (mixin == null) {
throw new Error("mixin '" + mixinName + "' can't be found");
}
_results.push(mixin.call(this, this));
}
return _results;
};
Factory.prototype.getConstructorArguments = function(traits) {
var args;
args = this.fromTraitOrThis('arguments', traits);
if ((args != null) && typeof args[0] === 'function') {
args = args[0].call(spectacular.env.currentExample.context);
}
return args || [];
};
Factory.prototype.findTrait = function(traitName) {
var trait, _ref;
trait = this.traits[traitName] || ((_ref = this.parent) != null ? _ref.findTrait(traitName) : void 0);
if (trait == null) {
throw new Error("unknown trait " + traitName);
}
return trait;
};
return Factory;
})(spectacular.factories.Trait);
spectacular.factoriesCache = {};
spectacular.factories.factory = function(name, options, block) {
var cache, fct, parent, _ref;
cache = spectacular.factoriesCache;
if (typeof options === 'function') {
_ref = [{}, options], options = _ref[0], block = _ref[1];
}
if (options["extends"] != null) {
parent = cache[options["extends"]];
if (parent == null) {
throw new Error("parent factory '" + options["extends"] + "' can't be found");
}
fct = cache[name] || (cache[name] = new spectacular.factories.Factory(name));
fct.parent = parent;
} else if (options["class"] != null) {
fct = cache[name] || (cache[name] = new spectacular.factories.Factory(name, options["class"]));
} else {
fct = cache[name];
if (fct == null) {
throw new Error('no class provided');
}
}
fct.globalize();
block.call(fct);
return fct.unglobalize();
};
spectacular.factories.mixins = {};
spectacular.factories.factoryMixin = function(name, block) {
return spectacular.factories.mixins[name] = block;
};
spectacular.factories.create = function() {
var fct, name, options, traits, _i;
name = arguments[0], traits = 3 <= arguments.length ? __slice.call(arguments, 1, _i = arguments.length - 1) : (_i = 1, []), options = arguments[_i++];
if (name == null) {
throw new Error('no factory name provided');
}
if (typeof options === 'string') {
traits.push(options);
options = null;
}
fct = spectacular.factoriesCache[name];
if (fct == null) {
throw new Error("missing factory " + name);
}
return fct.buildInstance(traits, options);
};
spectacular.Promise = (function() {
Promise.unit = function(value) {
var promise;
if (value == null) {
value = 0;
}
promise = new spectacular.Promise;
promise.resolve(value);
return promise;
};
Promise.all = function(promises) {
var promise, results, solved;
promise = new spectacular.Promise;
solved = 0;
results = [];
promises.forEach(function(p) {
return p.then(function(value) {
solved++;
results[promises.indexOf(p)] = value;
if (solved === promises.length) {
return promise.resolve(results);
}
}).fail(function(reason) {
return promise.reject(reason);
});
});
return promise;
};
function Promise() {
this.pending = true;
this.fulfilled = null;
this.value = void 0;
this.fulfilledHandlers = [];
this.errorHandlers = [];
this.progressHandlers = [];
}
Promise.prototype.isPending = function() {
return this.pending;
};
Promise.prototype.isResolved = function() {
return !this.pending;
};
Promise.prototype.isFulfilled = function() {
return !this.pending && this.fulfilled;
};
Promise.prototype.isRejected = function() {
return !this.pending && !this.fulfilled;
};
Promise.prototype.then = function(fulfilledHandler, errorHandler, progressHandler) {
var e, f, promise;
promise = new spectacular.Promise;
f = function(value) {
var err, res;
try {
res = typeof fulfilledHandler === "function" ? fulfilledHandler(value) : void 0;
} catch (_error) {
err = _error;
promise.reject(err);
return;
}
if ((res != null ? res.then : void 0) != null) {
return res.then(function(value) {
return promise.resolve(value);
}).fail(function(reason) {
return promise.reject(reason);
});
} else {
return promise.resolve(res);
}
};
e = function(reason) {
if (typeof errorHandler === "function") {
errorHandler(reason);
}
return promise.reject(reason);
};
if (this.pending) {
this.fulfilledHandlers.push(f);
this.errorHandlers.push(e);
if (progressHandler != null) {
this.progressHandlers.push(progressHandler);
}
} else {
if (this.fulfilled) {
f(this.value);
} else {
e(this.reason);
}
}
return promise;
};
Promise.prototype.fail = function(errorHandler) {
return this.then((function() {}), errorHandler);
};
Promise.prototype.resolve = function(value) {
if (!this.pending) {
return;
}
this.value = value;
this.fulfilled = true;
this.notifyHandlers();
return this.pending = false;
};
Promise.prototype.reject = function(reason) {
if (!this.pending) {
return;
}
this.reason = reason;
this.fulfilled = false;
this.notifyHandlers();
return this.pending = false;
};
Promise.prototype.notifyHandlers = function() {
var handler, _i, _j, _len, _len1, _ref, _ref1;
if (!this.pending) {
return;
}
if (this.fulfilled) {
_ref = this.fulfilledHandlers;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
handler = _ref[_i];
handler(this.value);
}
} else {
_ref1 = this.errorHandlers;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
handler = _ref1[_j];
handler(this.reason);
}
}
return this;
};
return Promise;
})();
spectacular.AsyncPromise = (function(_super) {
__extends(AsyncPromise, _super);
function AsyncPromise() {
this.run = __bind(this.run, this);
this.interval = null;
this.timeout = 5000;
this.message = 'Timed out';
AsyncPromise.__super__.constructor.call(this);
}
AsyncPromise.prototype.run = function() {
var lastTime,
_this = this;
lastTime = new Date();
return this.interval = setInterval(function() {
if (new Date() - lastTime >= _this.timeout) {
return _this.reject(new Error(_this.message));
}
}, 10);
};
AsyncPromise.prototype.reject = function(reason) {
clearInterval(this.interval);
return AsyncPromise.__super__.reject.call(this, reason);
};
AsyncPromise.prototype.resolve = function(value) {
clearInterval(this.interval);
return AsyncPromise.__super__.resolve.call(this, value);
};
AsyncPromise.prototype.rejectAfter = function(timeout, message) {
this.timeout = timeout;
this.message = message;
};
return AsyncPromise;
})(spectacular.Promise);
spectacular.Expectation = (function() {
function Expectation(example, actual, matcher, not, callstack, ownDescription) {
this.example = example;
this.actual = actual;
this.not = not != null ? not : false;
this.callstack = callstack;
this.createMessage = __bind(this.createMessage, this);
this.match = __bind(this.match, this);
this.matcher = Object.create(matcher);
this.ownDescription = ownDescription != null ? "" + ownDescription + " " : '';
}
Expectation.prototype.match = function() {
var promise, timeout,
_this = this;
promise = new spectacular.Promise;
timeout = null;
spectacular.Promise.unit().then(function() {
timeout = setTimeout(function() {
_this.success = false;
_this.trace = new Error('matcher timed out');
if (_this.not) {
_this.message = _this.matcher.messageForShouldnt;
} else {
_this.message = _this.matcher.messageForShould;
}
_this.description = "should" + (_this.not ? ' not' : '') + " " + _this.matcher.description;
return promise.resolve(_this.success);
}, _this.matcher.timeout || 5000);
return _this.matcher.match(_this.actual);
}).then(function(success) {
_this.success = success;
clearTimeout(timeout);
if (_this.not) {
_this.success = !_this.success;
}
_this.createMessage();
return promise.resolve(_this.success);
}).fail(function(trace) {
_this.trace = trace;
clearTimeout(timeout);
_this.success = false;
if (_this.matcher.message == null) {
_this.matcher.message = _this.trace.message;
}
if (_this.matcher.description == null) {
_this.matcher.description = '';
}
return promise.reject(_this.trace);
});
return promise;
};
Expectation.prototype.createMessage = function() {
var specIndex, stack;
if (this.not) {
this.message = this.matcher.messageForShouldnt;
} else {
this.message = this.matcher.messageForShould;
}
if (!this.success && (this.trace == null)) {
if (this.callstack.stack != null) {
stack = this.callstack.stack.split('\n');
specIndex = spectacular.env.runner.findSpecFileInStack(stack);
if (specIndex !== -1) {
this.callstack.stack = stack.slice(specIndex).join('\n');
}
}
this.trace = this.callstack;
}
this.description = "" + this.ownDescription + "should" + (this.not ? ' not' : '') + " " + this.matcher.description;
return this.fullDescription = "" + this.example.description + " " + this.ownDescription + "should" + (this.not ? ' not' : '') + " " + this.matcher.description;
};
return Expectation;
})();
spectacular.ExampleResult = (function() {
var _addExpectation;
ExampleResult.include(spectacular.HasCollection('expectations', 'expectation'));
function ExampleResult(example, state) {
this.example = example;
this.state = state;
this.expectations = [];
this.promise = spectacular.Promise.unit();
}
ExampleResult.prototype.hasFailures = function() {
return this.expectations.some(function(e) {
return !e.success;
});
};
_addExpectation = ExampleResult.prototype.addExpectation;
ExampleResult.prototype.addExpectation = function(expectation) {
var successHandler,
_this = this;
successHandler = function() {
return expectation.match().fail(function(e) {
return _this.example.error(e);
});
};
this.promise = this.promise.then(successHandler);
return _addExpectation.call(this, expectation);
};
return ExampleResult;
})();
spectacular.Example = (function() {
Example.include(spectacular.HasAncestors);
Example.include(spectacular.Describable);
Example.extend(spectacular.AncestorsProperties);
Example.followUp('subjectBlock');
Example.followUp('cascading');
Example.followUp('inclusiv