UNPKG

transactional

Version:

Reactive objects with transactional updates and automatic serialization

1,655 lines (1,438 loc) 640 kB
(function webpackUniversalModuleDefinition(root, factory) { if(typeof exports === 'object' && typeof module === 'object') module.exports = factory(); else if(typeof define === 'function' && define.amd) define([], factory); else if(typeof exports === 'object') exports["Transactional"] = factory(); else root["Transactional"] = factory(); })(this, function() { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; /******/ /******/ // The require function /******/ function __webpack_require__(moduleId) { /******/ /******/ // Check if module is in cache /******/ if(installedModules[moduleId]) /******/ return installedModules[moduleId].exports; /******/ /******/ // Create a new module (and put it into the cache) /******/ var module = installedModules[moduleId] = { /******/ exports: {}, /******/ id: moduleId, /******/ loaded: false /******/ }; /******/ /******/ // Execute the module function /******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); /******/ /******/ // Flag the module as loaded /******/ module.loaded = true; /******/ /******/ // Return the exports of the module /******/ return module.exports; /******/ } /******/ /******/ /******/ // expose the modules object (__webpack_modules__) /******/ __webpack_require__.m = modules; /******/ /******/ // expose the module cache /******/ __webpack_require__.c = installedModules; /******/ /******/ // __webpack_public_path__ /******/ __webpack_require__.p = ""; /******/ /******/ // Load entry module and return exports /******/ return __webpack_require__(0); /******/ }) /************************************************************************/ /******/ ([ /* 0 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;'use strict'; (function (factory) { if (typeof module === 'object' && typeof module.exports === 'object') { var v = factory(__webpack_require__(47), exports);if (v !== undefined) module.exports = v; } else if (true) { !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__, exports, __webpack_require__(5), __webpack_require__(6)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } })(function (require, exports) { "use strict"; require('./src/class'); require('./primitives'); }); //# sourceMappingURL=index.js.map /***/ }, /* 1 */, /* 2 */, /* 3 */, /* 4 */, /* 5 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;"use strict"; var __extends = undefined && undefined.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var __decorate = undefined && undefined.__decorate || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; (function (factory) { if (typeof module === 'object' && typeof module.exports === 'object') { var v = factory(__webpack_require__(47), exports);if (v !== undefined) module.exports = v; } else if (true) { !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__, exports, !(function webpackMissingModule() { var e = new Error("Cannot find module \"../tools\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()), __webpack_require__(7), __webpack_require__(52)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } })(function (require, exports) { "use strict"; var tools_1 = require('../tools'); var chai_1 = require('chai'); var mocha_1 = require('mocha'); mocha_1.describe('Mixins', function () { mocha_1.it('merges objects to the prototype, if they are not defined', function () {}); mocha_1.it('works on a plain class', function () {}); mocha_1.describe('mixin rules', function () { mocha_1.it('merges object properties'); mocha_1.it('merges rules on inheritance'); mocha_1.it('works on the plain class'); mocha_1.describe('methods composition', function () { mocha_1.it('execute methods sequentially'); mocha_1.it('execute methods in reverse order'); mocha_1.it('pipeline methods passing the first argument through'); }); mocha_1.describe('boolean methods composition', function () { mocha_1.it('joins checks by "and"'); mocha_1.it('joins checks by "or"'); }); }); }); mocha_1.describe('Class#define', function () { mocha_1.it('adds members to the prototype', function () { var C = (function (_super) { __extends(C, _super); function C() { _super.apply(this, arguments); } C = __decorate([tools_1.define({ a: 'a' })], C); return C; })(tools_1.Class); chai_1.expect(C.prototype.a).equal('a'); }); mocha_1.it('defines properties passed in "properties" spec', function () { var C = (function (_super) { __extends(C, _super); function C() { _super.apply(this, arguments); } C = __decorate([tools_1.define({ properties: { p: { get: function get() { return "Hey"; } } } })], C); return C; })(tools_1.Class); var c = new C(); chai_1.expect(c.p).to.equal('Hey'); }); mocha_1.it('clear up "create" factory method on inheritance', function () { var A = (function (_super) { __extends(A, _super); function A() { _super.apply(this, arguments); } A.create = function () { return "Hello"; }; A = __decorate([tools_1.define], A); return A; })(tools_1.Class); var B = (function (_super) { __extends(B, _super); function B() { _super.apply(this, arguments); } B = __decorate([tools_1.define], B); return B; })(A); chai_1.expect(B.create()).to.be.instanceOf(B); }); mocha_1.it('merges mixin rules on inheritance', function () { var A = (function (_super) { __extends(A, _super); function A() { _super.apply(this, arguments); } A.create = function () { return "Hello"; }; A = __decorate([tools_1.define({ mixinRules: { a: 'merge' } })], A); return A; })(tools_1.Class); chai_1.expect(A._mixinRules.a).to.eql('merge'); var B = (function (_super) { __extends(B, _super); function B() { _super.apply(this, arguments); } B = __decorate([tools_1.define({ mixinRules: { b: 'merge' } })], B); return B; })(A); chai_1.expect(B._mixinRules.a).to.eql('merge'); chai_1.expect(B._mixinRules.b).to.eql('merge'); }); }); }); //# sourceMappingURL=class.js.map /***/ }, /* 6 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;"use strict"; var __extends = undefined && undefined.__extends || function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; function __() { this.constructor = d; } d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); }; var __decorate = undefined && undefined.__decorate || function (decorators, target, key, desc) { var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; return c > 3 && r && Object.defineProperty(target, key, r), r; }; (function (factory) { if (typeof module === 'object' && typeof module.exports === 'object') { var v = factory(__webpack_require__(47), exports);if (v !== undefined) module.exports = v; } else if (true) { !(__WEBPACK_AMD_DEFINE_ARRAY__ = [__webpack_require__, exports, !(function webpackMissingModule() { var e = new Error("Cannot find module \"../tools\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()), !(function webpackMissingModule() { var e = new Error("Cannot find module \"../src/record/\""); e.code = 'MODULE_NOT_FOUND'; throw e; }()), __webpack_require__(7)], __WEBPACK_AMD_DEFINE_FACTORY__ = (factory), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.apply(exports, __WEBPACK_AMD_DEFINE_ARRAY__)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)); } })(function (require, exports) { "use strict"; var tools_1 = require('../tools'); var _1 = require('../src/record/'); var chai_1 = require('chai'); describe('Record', function () { it("can be instantiated", function () { new _1.Record(); }); describe('Subclass', function () { it("attaches properties to prototype", function () { var M = (function (_super) { __extends(M, _super); function M() { _super.apply(this, arguments); } M = __decorate([tools_1.define({ a: 'a' })], M); return M; })(_1.Record); chai_1.expect(M.prototype.a).to.eql('a'); }); }); describe("Attribute spec", function () { describe('...as constructors', function () { var M = (function (_super) { __extends(M, _super); function M() { _super.apply(this, arguments); } M = __decorate([tools_1.define({ attributes: { s: String, n: Number, b: Boolean, o: Object, a: Array, d: Date } })], M); return M; })(_1.Record); it("invokes constructor to create defaults", function () { var m = new M(); chai_1.expect(m.s).to.equal(''); chai_1.expect(m.n).to.equal(0); chai_1.expect(m.b).to.equal(false); chai_1.expect(m.o).to.eql({}); chai_1.expect(m.a).to.eql([]); chai_1.expect(m.d).to.be["instanceof"](Date); }); it("convert values to defined type in 'new'", function () { var m = new M({ s: 55, n: "1", b: 'not bool', o: "not an object", a: "not an array", d: 678678678 }); chai_1.expect(m.s).to.equal('55'); chai_1.expect(m.n).to.equal(1); chai_1.expect(m.b).to.equal(true); chai_1.expect(m.o).to.eql({}); chai_1.expect(m.a).to.eql([]); chai_1.expect(m.d).to.be["instanceof"](Date); }); it("convert values to defined types on assignment", function () { var m = new M(); m.s = 55; m.n = "1"; m.b = 'not bool'; m.o = "not an object"; m.a = "not an array"; m.d = 678678678; chai_1.expect(m.s).to.equal('55'); chai_1.expect(m.n).to.equal(1); chai_1.expect(m.b).to.equal(true); chai_1.expect(m.o).to.eql({}); chai_1.expect(m.a).to.eql([]); chai_1.expect(m.d).to.be["instanceof"](Date); }); it("convert values to defined types on set", function () { var m = new M(); m.set({ s: 55, n: "1", b: 'not bool', o: "not an object", a: "not an array", d: 678678678 }); chai_1.expect(m.s).to.equal('55'); chai_1.expect(m.n).to.equal(1); chai_1.expect(m.b).to.equal(true); chai_1.expect(m.o).to.eql({}); chai_1.expect(m.a).to.eql([]); chai_1.expect(m.d).to.be["instanceof"](Date); }); }); describe('...as default values', function () { var M = (function (_super) { __extends(M, _super); function M() { _super.apply(this, arguments); } M = __decorate([tools_1.define({ attributes: { s: 'b', n: 1, b: true, o: {}, a: [], d: new Date() } })], M); return M; })(_1.Record); it("accepts values as type spec", function () { var m = new M(); chai_1.expect(m.s).to.equal('b'); chai_1.expect(m.n).to.equal(1); chai_1.expect(m.b).to.equal(true); chai_1.expect(m.o).to.not.equal({}); chai_1.expect(m.o).to.eql({}); chai_1.expect(m.a).to.not.equal([]); chai_1.expect(m.a).to.eql([]); chai_1.expect(m.d).to.be["instanceof"](Date); }); it("infers types from values", function () { var m = new M(), _attributes = m._attributes; chai_1.expect(_attributes.s.type).to.equal(String); chai_1.expect(_attributes.n.type).to.equal(Number); chai_1.expect(_attributes.b.type).to.equal(Boolean); chai_1.expect(_attributes.o.type).to.equal(Object); chai_1.expect(_attributes.a.type).to.equal(Array); chai_1.expect(_attributes.d.type).to.equal(Date); }); }); describe('...as constructors with values', function () { it("converts default values to defined types", function () { var M = (function (_super) { __extends(M, _super); function M() { _super.apply(this, arguments); } M = __decorate([tools_1.define({ attributes: { s: String.value(55), n: Number.value("1"), b: Boolean.value("some"), o: Object.value("not an object"), a: Array.value("not an array"), d: Date.value(22222) } })], M); return M; })(_1.Record); var m = new M(); chai_1.expect(m.s).to.equal('55'); chai_1.expect(m.n).to.equal(1); chai_1.expect(m.b).to.equal(true); chai_1.expect(m.o).to.eql({}); chai_1.expect(m.a).to.eql([]); chai_1.expect(m.d).to.be["instanceof"](Date); }); it("accepts null as default value", function () { var M = (function (_super) { __extends(M, _super); function M() { _super.apply(this, arguments); } M = __decorate([tools_1.define({ attributes: { s: String.value(null), n: Number.value(null), b: Boolean.value(null), o: Object.value(null), a: Array.value(null), d: Date.value(null) } })], M); return M; })(_1.Record); var m = new M(); chai_1.expect(m.s).to.equal(null); chai_1.expect(m.n).to.equal(null); chai_1.expect(m.b).to.equal(null); chai_1.expect(m.o).to.eql(null); chai_1.expect(m.a).to.eql(null); chai_1.expect(m.d).to.eql(null); }); }); }); describe("Record's collection", function () { it("is defined in the base Record", function () { chai_1.expect(_1.Record.Collection).to.be.a('function'); chai_1.expect(_1.Record.Collection.prototype.Record).to.eql(_1.Record); }); it("is created on Record's extension", function () { var M = (function (_super) { __extends(M, _super); function M() { _super.apply(this, arguments); } M = __decorate([tools_1.define], M); return M; })(_1.Record); var prototype = M.Collection.prototype; chai_1.expect(prototype).to.be["instanceof"](_1.Record.Collection); chai_1.expect(prototype.Record).to.eql(M); }); it("takes properties from .collection", function () { var M = (function (_super) { __extends(M, _super); function M() { _super.apply(this, arguments); } M = __decorate([tools_1.define({ collection: { a: 'a' } })], M); return M; })(_1.Record); chai_1.expect(M.Collection.prototype.a).to.eql('a'); }); it("can be defined separately", function () { var C = (function (_super) { __extends(C, _super); function C() { _super.apply(this, arguments); } C = __decorate([tools_1.define({ a: 'a' })], C); return C; })(Collection); var M = (function (_super) { __extends(M, _super); function M() { _super.apply(this, arguments); } M = __decorate([tools_1.define({ collection: C })], M); return M; })(_1.Record); chai_1.expect(M.Collection).to.eql(C); var prototype = M.Collection.prototype; chai_1.expect(prototype).to.be["instanceof"](_1.Record.Collection); chai_1.expect(prototype.a).to.eql('a'); chai_1.expect(prototype.Record).to.eql(M); }); }); describe('Record pre-definition', function () { var M1 = (function (_super) { __extends(M1, _super); function M1() { _super.apply(this, arguments); } M1 = __decorate([tools_1.define], M1); return M1; })(_1.Record); var M2 = (function (_super) { __extends(M2, _super); function M2() { _super.apply(this, arguments); } return M2; })(_1.Record); M2.define(); it('predefine collection types', function () { chai_1.expect(M1.Collection).to.be.func; chai_1.expect(M2.Collection).to.be.func; }); it("can't be instantiated", function () { new M1(); }); it('support forward declaration', function () { var M = (function (_super) { __extends(M, _super); function M() { _super.apply(this, arguments); } M = __decorate([tools_1.define], M); return M; })(_1.Record); chai_1.expect(M.Collection).to.be.a('function'); chai_1.expect(M.Collection.prototype.Record).to.eql(M); M.define({ a: 'a' }); chai_1.expect(M.prototype.a).to.eql('a'); }); it('can be defined', function () { M1.define({ a: 'first', collection: { b: 'second' } }); M2.define({ a: 'first' }); M2.Collection.define({ b: 'second' }); }); }); }); }); //# sourceMappingURL=primitives.js.map /***/ }, /* 7 */ /***/ function(module, exports, __webpack_require__) { module.exports = __webpack_require__(8); /***/ }, /* 8 */ /***/ function(module, exports, __webpack_require__) { /*! * chai * Copyright(c) 2011-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ var used = [] , exports = module.exports = {}; /*! * Chai version */ exports.version = '3.5.0'; /*! * Assertion Error */ exports.AssertionError = __webpack_require__(9); /*! * Utils for plugins (not exported) */ var util = __webpack_require__(10); /** * # .use(function) * * Provides a way to extend the internals of Chai * * @param {Function} * @returns {this} for chaining * @api public */ exports.use = function (fn) { if (!~used.indexOf(fn)) { fn(this, util); used.push(fn); } return this; }; /*! * Utility Functions */ exports.util = util; /*! * Configuration */ var config = __webpack_require__(23); exports.config = config; /*! * Primary `Assertion` prototype */ var assertion = __webpack_require__(42); exports.use(assertion); /*! * Core Assertions */ var core = __webpack_require__(43); exports.use(core); /*! * Expect interface */ var expect = __webpack_require__(44); exports.use(expect); /*! * Should interface */ var should = __webpack_require__(45); exports.use(should); /*! * Assert interface */ var assert = __webpack_require__(46); exports.use(assert); /***/ }, /* 9 */ /***/ function(module, exports) { /*! * assertion-error * Copyright(c) 2013 Jake Luer <jake@qualiancy.com> * MIT Licensed */ /*! * Return a function that will copy properties from * one object to another excluding any originally * listed. Returned function will create a new `{}`. * * @param {String} excluded properties ... * @return {Function} */ function exclude () { var excludes = [].slice.call(arguments); function excludeProps (res, obj) { Object.keys(obj).forEach(function (key) { if (!~excludes.indexOf(key)) res[key] = obj[key]; }); } return function extendExclude () { var args = [].slice.call(arguments) , i = 0 , res = {}; for (; i < args.length; i++) { excludeProps(res, args[i]); } return res; }; }; /*! * Primary Exports */ module.exports = AssertionError; /** * ### AssertionError * * An extension of the JavaScript `Error` constructor for * assertion and validation scenarios. * * @param {String} message * @param {Object} properties to include (optional) * @param {callee} start stack function (optional) */ function AssertionError (message, _props, ssf) { var extend = exclude('name', 'message', 'stack', 'constructor', 'toJSON') , props = extend(_props || {}); // default values this.message = message || 'Unspecified AssertionError'; this.showDiff = false; // copy from properties for (var key in props) { this[key] = props[key]; } // capture stack trace ssf = ssf || arguments.callee; if (ssf && Error.captureStackTrace) { Error.captureStackTrace(this, ssf); } else { this.stack = new Error().stack; } } /*! * Inherit from Error.prototype */ AssertionError.prototype = Object.create(Error.prototype); /*! * Statically set name */ AssertionError.prototype.name = 'AssertionError'; /*! * Ensure correct constructor */ AssertionError.prototype.constructor = AssertionError; /** * Allow errors to be converted to JSON for static transfer. * * @param {Boolean} include stack (default: `true`) * @return {Object} object that can be `JSON.stringify` */ AssertionError.prototype.toJSON = function (stack) { var extend = exclude('constructor', 'toJSON', 'stack') , props = extend({ name: this.name }, this); // include stack if exists and not turned off if (false !== stack && this.stack) { props.stack = this.stack; } return props; }; /***/ }, /* 10 */ /***/ function(module, exports, __webpack_require__) { /*! * chai * Copyright(c) 2011 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /*! * Main exports */ var exports = module.exports = {}; /*! * test utility */ exports.test = __webpack_require__(11); /*! * type utility */ exports.type = __webpack_require__(13); /*! * expectTypes utility */ exports.expectTypes = __webpack_require__(15); /*! * message utility */ exports.getMessage = __webpack_require__(16); /*! * actual utility */ exports.getActual = __webpack_require__(17); /*! * Inspect util */ exports.inspect = __webpack_require__(18); /*! * Object Display util */ exports.objDisplay = __webpack_require__(22); /*! * Flag utility */ exports.flag = __webpack_require__(12); /*! * Flag transferring utility */ exports.transferFlags = __webpack_require__(24); /*! * Deep equal utility */ exports.eql = __webpack_require__(25); /*! * Deep path value */ exports.getPathValue = __webpack_require__(33); /*! * Deep path info */ exports.getPathInfo = __webpack_require__(34); /*! * Check if a property exists */ exports.hasProperty = __webpack_require__(35); /*! * Function name */ exports.getName = __webpack_require__(19); /*! * add Property */ exports.addProperty = __webpack_require__(36); /*! * add Method */ exports.addMethod = __webpack_require__(37); /*! * overwrite Property */ exports.overwriteProperty = __webpack_require__(38); /*! * overwrite Method */ exports.overwriteMethod = __webpack_require__(39); /*! * Add a chainable method */ exports.addChainableMethod = __webpack_require__(40); /*! * Overwrite chainable method */ exports.overwriteChainableMethod = __webpack_require__(41); /***/ }, /* 11 */ /***/ function(module, exports, __webpack_require__) { /*! * Chai - test utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /*! * Module dependancies */ var flag = __webpack_require__(12); /** * # test(object, expression) * * Test and object for expression. * * @param {Object} object (constructed Assertion) * @param {Arguments} chai.Assertion.prototype.assert arguments * @namespace Utils * @name test */ module.exports = function (obj, args) { var negate = flag(obj, 'negate') , expr = args[0]; return negate ? !expr : expr; }; /***/ }, /* 12 */ /***/ function(module, exports) { /*! * Chai - flag utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /** * ### flag(object, key, [value]) * * Get or set a flag value on an object. If a * value is provided it will be set, else it will * return the currently set value or `undefined` if * the value is not set. * * utils.flag(this, 'foo', 'bar'); // setter * utils.flag(this, 'foo'); // getter, returns `bar` * * @param {Object} object constructed Assertion * @param {String} key * @param {Mixed} value (optional) * @namespace Utils * @name flag * @api private */ module.exports = function (obj, key, value) { var flags = obj.__flags || (obj.__flags = Object.create(null)); if (arguments.length === 3) { flags[key] = value; } else { return flags[key]; } }; /***/ }, /* 13 */ /***/ function(module, exports, __webpack_require__) { module.exports = __webpack_require__(14); /***/ }, /* 14 */ /***/ function(module, exports) { /*! * type-detect * Copyright(c) 2013 jake luer <jake@alogicalparadox.com> * MIT Licensed */ /*! * Primary Exports */ var exports = module.exports = getType; /** * ### typeOf (obj) * * Use several different techniques to determine * the type of object being tested. * * * @param {Mixed} object * @return {String} object type * @api public */ var objectTypeRegexp = /^\[object (.*)\]$/; function getType(obj) { var type = Object.prototype.toString.call(obj).match(objectTypeRegexp)[1].toLowerCase(); // Let "new String('')" return 'object' if (typeof Promise === 'function' && obj instanceof Promise) return 'promise'; // PhantomJS has type "DOMWindow" for null if (obj === null) return 'null'; // PhantomJS has type "DOMWindow" for undefined if (obj === undefined) return 'undefined'; return type; } exports.Library = Library; /** * ### Library * * Create a repository for custom type detection. * * ```js * var lib = new type.Library; * ``` * */ function Library() { if (!(this instanceof Library)) return new Library(); this.tests = {}; } /** * #### .of (obj) * * Expose replacement `typeof` detection to the library. * * ```js * if ('string' === lib.of('hello world')) { * // ... * } * ``` * * @param {Mixed} object to test * @return {String} type */ Library.prototype.of = getType; /** * #### .define (type, test) * * Add a test to for the `.test()` assertion. * * Can be defined as a regular expression: * * ```js * lib.define('int', /^[0-9]+$/); * ``` * * ... or as a function: * * ```js * lib.define('bln', function (obj) { * if ('boolean' === lib.of(obj)) return true; * var blns = [ 'yes', 'no', 'true', 'false', 1, 0 ]; * if ('string' === lib.of(obj)) obj = obj.toLowerCase(); * return !! ~blns.indexOf(obj); * }); * ``` * * @param {String} type * @param {RegExp|Function} test * @api public */ Library.prototype.define = function(type, test) { if (arguments.length === 1) return this.tests[type]; this.tests[type] = test; return this; }; /** * #### .test (obj, test) * * Assert that an object is of type. Will first * check natives, and if that does not pass it will * use the user defined custom tests. * * ```js * assert(lib.test('1', 'int')); * assert(lib.test('yes', 'bln')); * ``` * * @param {Mixed} object * @param {String} type * @return {Boolean} result * @api public */ Library.prototype.test = function(obj, type) { if (type === getType(obj)) return true; var test = this.tests[type]; if (test && 'regexp' === getType(test)) { return test.test(obj); } else if (test && 'function' === getType(test)) { return test(obj); } else { throw new ReferenceError('Type test "' + type + '" not defined or invalid.'); } }; /***/ }, /* 15 */ /***/ function(module, exports, __webpack_require__) { /*! * Chai - expectTypes utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /** * ### expectTypes(obj, types) * * Ensures that the object being tested against is of a valid type. * * utils.expectTypes(this, ['array', 'object', 'string']); * * @param {Mixed} obj constructed Assertion * @param {Array} type A list of allowed types for this assertion * @namespace Utils * @name expectTypes * @api public */ var AssertionError = __webpack_require__(9); var flag = __webpack_require__(12); var type = __webpack_require__(13); module.exports = function (obj, types) { var obj = flag(obj, 'object'); types = types.map(function (t) { return t.toLowerCase(); }); types.sort(); // Transforms ['lorem', 'ipsum'] into 'a lirum, or an ipsum' var str = types.map(function (t, index) { var art = ~[ 'a', 'e', 'i', 'o', 'u' ].indexOf(t.charAt(0)) ? 'an' : 'a'; var or = types.length > 1 && index === types.length - 1 ? 'or ' : ''; return or + art + ' ' + t; }).join(', '); if (!types.some(function (expected) { return type(obj) === expected; })) { throw new AssertionError( 'object tested must be ' + str + ', but ' + type(obj) + ' given' ); } }; /***/ }, /* 16 */ /***/ function(module, exports, __webpack_require__) { /*! * Chai - message composition utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /*! * Module dependancies */ var flag = __webpack_require__(12) , getActual = __webpack_require__(17) , inspect = __webpack_require__(18) , objDisplay = __webpack_require__(22); /** * ### .getMessage(object, message, negateMessage) * * Construct the error message based on flags * and template tags. Template tags will return * a stringified inspection of the object referenced. * * Message template tags: * - `#{this}` current asserted object * - `#{act}` actual value * - `#{exp}` expected value * * @param {Object} object (constructed Assertion) * @param {Arguments} chai.Assertion.prototype.assert arguments * @namespace Utils * @name getMessage * @api public */ module.exports = function (obj, args) { var negate = flag(obj, 'negate') , val = flag(obj, 'object') , expected = args[3] , actual = getActual(obj, args) , msg = negate ? args[2] : args[1] , flagMsg = flag(obj, 'message'); if(typeof msg === "function") msg = msg(); msg = msg || ''; msg = msg .replace(/#\{this\}/g, function () { return objDisplay(val); }) .replace(/#\{act\}/g, function () { return objDisplay(actual); }) .replace(/#\{exp\}/g, function () { return objDisplay(expected); }); return flagMsg ? flagMsg + ': ' + msg : msg; }; /***/ }, /* 17 */ /***/ function(module, exports) { /*! * Chai - getActual utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /** * # getActual(object, [actual]) * * Returns the `actual` value for an Assertion * * @param {Object} object (constructed Assertion) * @param {Arguments} chai.Assertion.prototype.assert arguments * @namespace Utils * @name getActual */ module.exports = function (obj, args) { return args.length > 4 ? args[4] : obj._obj; }; /***/ }, /* 18 */ /***/ function(module, exports, __webpack_require__) { // This is (almost) directly from Node.js utils // https://github.com/joyent/node/blob/f8c335d0caf47f16d31413f89aa28eda3878e3aa/lib/util.js var getName = __webpack_require__(19); var getProperties = __webpack_require__(20); var getEnumerableProperties = __webpack_require__(21); module.exports = inspect; /** * Echos the value of a value. Trys to print the value out * in the best way possible given the different types. * * @param {Object} obj The object to print out. * @param {Boolean} showHidden Flag that shows hidden (not enumerable) * properties of objects. * @param {Number} depth Depth in which to descend in object. Default is 2. * @param {Boolean} colors Flag to turn on ANSI escape codes to color the * output. Default is false (no coloring). * @namespace Utils * @name inspect */ function inspect(obj, showHidden, depth, colors) { var ctx = { showHidden: showHidden, seen: [], stylize: function (str) { return str; } }; return formatValue(ctx, obj, (typeof depth === 'undefined' ? 2 : depth)); } // Returns true if object is a DOM element. var isDOMElement = function (object) { if (typeof HTMLElement === 'object') { return object instanceof HTMLElement; } else { return object && typeof object === 'object' && object.nodeType === 1 && typeof object.nodeName === 'string'; } }; function formatValue(ctx, value, recurseTimes) { // Provide a hook for user-specified inspect functions. // Check that value is an object with an inspect function on it if (value && typeof value.inspect === 'function' && // Filter out the util module, it's inspect function is special value.inspect !== exports.inspect && // Also filter out any prototype objects using the circular check. !(value.constructor && value.constructor.prototype === value)) { var ret = value.inspect(recurseTimes); if (typeof ret !== 'string') { ret = formatValue(ctx, ret, recurseTimes); } return ret; } // Primitive types cannot have properties var primitive = formatPrimitive(ctx, value); if (primitive) { return primitive; } // If this is a DOM element, try to get the outer HTML. if (isDOMElement(value)) { if ('outerHTML' in value) { return value.outerHTML; // This value does not have an outerHTML attribute, // it could still be an XML element } else { // Attempt to serialize it try { if (document.xmlVersion) { var xmlSerializer = new XMLSerializer(); return xmlSerializer.serializeToString(value); } else { // Firefox 11- do not support outerHTML // It does, however, support innerHTML // Use the following to render the element var ns = "http://www.w3.org/1999/xhtml"; var container = document.createElementNS(ns, '_'); container.appendChild(value.cloneNode(false)); html = container.innerHTML .replace('><', '>' + value.innerHTML + '<'); container.innerHTML = ''; return html; } } catch (err) { // This could be a non-native DOM implementation, // continue with the normal flow: // printing the element as if it is an object. } } } // Look up the keys of the object. var visibleKeys = getEnumerableProperties(value); var keys = ctx.showHidden ? getProperties(value) : visibleKeys; // Some type of object without properties can be shortcutted. // In IE, errors have a single `stack` property, or if they are vanilla `Error`, // a `stack` plus `description` property; ignore those for consistency. if (keys.length === 0 || (isError(value) && ( (keys.length === 1 && keys[0] === 'stack') || (keys.length === 2 && keys[0] === 'description' && keys[1] === 'stack') ))) { if (typeof value === 'function') { var name = getName(value); var nameSuffix = name ? ': ' + name : ''; return ctx.stylize('[Function' + nameSuffix + ']', 'special'); } if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } if (isDate(value)) { return ctx.stylize(Date.prototype.toUTCString.call(value), 'date'); } if (isError(value)) { return formatError(value); } } var base = '', array = false, braces = ['{', '}']; // Make Array say that they are Array if (isArray(value)) { array = true; braces = ['[', ']']; } // Make functions say that they are functions if (typeof value === 'function') { var name = getName(value); var nameSuffix = name ? ': ' + name : ''; base = ' [Function' + nameSuffix + ']'; } // Make RegExps say that they are RegExps if (isRegExp(value)) { base = ' ' + RegExp.prototype.toString.call(value); } // Make dates with properties first say the date if (isDate(value)) { base = ' ' + Date.prototype.toUTCString.call(value); } // Make error with message first say the error if (isError(value)) { return formatError(value); } if (keys.length === 0 && (!array || value.length == 0)) { return braces[0] + base + braces[1]; } if (recurseTimes < 0) { if (isRegExp(value)) { return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp'); } else { return ctx.stylize('[Object]', 'special'); } } ctx.seen.push(value); var output; if (array) { output = formatArray(ctx, value, recurseTimes, visibleKeys, keys); } else { output = keys.map(function(key) { return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array); }); } ctx.seen.pop(); return reduceToSingleString(output, base, braces); } function formatPrimitive(ctx, value) { switch (typeof value) { case 'undefined': return ctx.stylize('undefined', 'undefined'); case 'string': var simple = '\'' + JSON.stringify(value).replace(/^"|"$/g, '') .replace(/'/g, "\\'") .replace(/\\"/g, '"') + '\''; return ctx.stylize(simple, 'string'); case 'number': if (value === 0 && (1/value) === -Infinity) { return ctx.stylize('-0', 'number'); } return ctx.stylize('' + value, 'number'); case 'boolean': return ctx.stylize('' + value, 'boolean'); } // For some reason typeof null is "object", so special case here. if (value === null) { return ctx.stylize('null', 'null'); } } function formatError(value) { return '[' + Error.prototype.toString.call(value) + ']'; } function formatArray(ctx, value, recurseTimes, visibleKeys, keys) { var output = []; for (var i = 0, l = value.length; i < l; ++i) { if (Object.prototype.hasOwnProperty.call(value, String(i))) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, String(i), true)); } else { output.push(''); } } keys.forEach(function(key) { if (!key.match(/^\d+$/)) { output.push(formatProperty(ctx, value, recurseTimes, visibleKeys, key, true)); } }); return output; } function formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) { var name, str; if (value.__lookupGetter__) { if (value.__lookupGetter__(key)) { if (value.__lookupSetter__(key)) { str = ctx.stylize('[Getter/Setter]', 'special'); } else { str = ctx.stylize('[Getter]', 'special'); } } else { if (value.__lookupSetter__(key)) { str = ctx.stylize('[Setter]', 'special'); } } } if (visibleKeys.indexOf(key) < 0) { name = '[' + key + ']'; } if (!str) { if (ctx.seen.indexOf(value[key]) < 0) { if (recurseTimes === null) { str = formatValue(ctx, value[key], null); } else { str = formatValue(ctx, value[key], recurseTimes - 1); } if (str.indexOf('\n') > -1) { if (array) { str = str.split('\n').map(function(line) { return ' ' + line; }).join('\n').substr(2); } else { str = '\n' + str.split('\n').map(function(line) { return ' ' + line; }).join('\n'); } } } else { str = ctx.stylize('[Circular]', 'special'); } } if (typeof name === 'undefined') { if (array && key.match(/^\d+$/)) { return str; } name = JSON.stringify('' + key); if (name.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)) { name = name.substr(1, name.length - 2); name = ctx.stylize(name, 'name'); } else { name = name.replace(/'/g, "\\'") .replace(/\\"/g, '"') .replace(/(^"|"$)/g, "'"); name = ctx.stylize(name, 'string'); } } return name + ': ' + str; } function reduceToSingleString(output, base, braces) { var numLinesEst = 0; var length = output.reduce(function(prev, cur) { numLinesEst++; if (cur.indexOf('\n') >= 0) numLinesEst++; return prev + cur.length + 1; }, 0); if (length > 60) { return braces[0] + (base === '' ? '' : base + '\n ') + ' ' + output.join(',\n ') + ' ' + braces[1]; } return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1]; } function isArray(ar) { return Array.isArray(ar) || (typeof ar === 'object' && objectToString(ar) === '[object Array]'); } function isRegExp(re) { return typeof re === 'object' && objectToString(re) === '[object RegExp]'; } function isDate(d) { return typeof d === 'object' && objectToString(d) === '[object Date]'; } function isError(e) { return typeof e === 'object' && objectToString(e) === '[object Error]'; } function objectToString(o) { return Object.prototype.toString.call(o); } /***/ }, /* 19 */ /***/ function(module, exports) { /*! * Chai - getName utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /** * # getName(func) * * Gets the name of a function, in a cross-browser way. * * @param {Function} a function (usually a constructor) * @namespace Utils * @name getName */ module.exports = function (func) { if (func.name) return func.name; var match = /^\s?function ([^(]*)\(/.exec(func); return match && match[1] ? match[1] : ""; }; /***/ }, /* 20 */ /***/ function(module, exports) { /*! * Chai - getProperties utility * Copyright(c) 2012-2014 Jake Luer <jake@alogicalparadox.com> * MIT Licensed */ /** * ### .getProperties(object) * * This allows the retrieval of property names of an object, enumerable or not, * inherited or not. * * @param {