├── spec ├── index.d.ts ├── common │ ├── dateconverter.ts │ └── dateconverter.js ├── serialize.ts ├── index.ts ├── index.js ├── serialize.js └── reports │ └── Test Results - spec_index_ts - 20160816.html ├── .bowerrc ├── .gitattributes ├── typings.json ├── bower.json ├── .gitignore ├── libs ├── utils.d.ts ├── utils.ts └── utils.js ├── tsconfig.json ├── bower_components ├── mocha │ ├── bower.json │ ├── media │ │ └── logo.svg │ ├── .bower.json │ ├── LICENSE │ ├── Readme.md │ ├── mocha.css │ └── History.md └── chai │ ├── bower.json │ ├── karma.conf.js │ ├── .bower.json │ ├── karma.sauce.js │ ├── package.json │ ├── component.json │ ├── sauce.browsers.js │ ├── README.md │ ├── ReleaseNotes.md │ └── History.md ├── LICENSE ├── package.json ├── index.d.ts ├── README.md ├── index.js ├── typings ├── mocha │ └── mocha.d.ts └── chai │ └── chai.d.ts └── index.ts /spec/index.d.ts: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.bowerrc: -------------------------------------------------------------------------------- 1 | { 2 | "directory": "bower_components" 3 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | *.js linguist-language=Typescript 2 | *.css linguist-language=Typescript 3 | *.html linguist-language=Typescript -------------------------------------------------------------------------------- /typings.json: -------------------------------------------------------------------------------- 1 | { 2 | "globalDependencies": { 3 | "reflect-metadata": "registry:dt/reflect-metadata#0.0.0+20161005184000" 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "index", 3 | "private": true, 4 | "dependencies": { 5 | "chai": "~1.8.0", 6 | "mocha": "~1.14.0" 7 | }, 8 | "devDependencies": {} 9 | } 10 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Created by .ignore support plugin (hsz.mobi) 2 | 3 | #libraries 4 | node_modules 5 | 6 | #ide settings 7 | .idea 8 | .log 9 | 10 | #source map 11 | *.map 12 | documentation/ 13 | -------------------------------------------------------------------------------- /libs/utils.d.ts: -------------------------------------------------------------------------------- 1 | export declare function isTargetType(val: any, type: "object" | "string"): boolean; 2 | export declare function isPrimitiveOrPrimitiveClass(obj: any): boolean; 3 | export declare function isArrayOrArrayClass(clazz: Function): boolean; 4 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "module": "commonjs", 4 | "target": "es5", 5 | "sourceMap": true, 6 | "experimentalDecorators": true, 7 | "emitDecoratorMetadata": true, 8 | "noImplicitAny": true 9 | }, 10 | "exclude": [ 11 | "node_modules" 12 | ] 13 | } -------------------------------------------------------------------------------- /spec/common/dateconverter.ts: -------------------------------------------------------------------------------- 1 | import {ICustomConverter} from '../../index'; 2 | 3 | const dateConverter: ICustomConverter = { 4 | fromJson(data: any): any { 5 | return new Date(data); 6 | }, 7 | 8 | toJson(data: any): any { 9 | return 'some-date'; 10 | } 11 | }; 12 | 13 | export default dateConverter; -------------------------------------------------------------------------------- /spec/common/dateconverter.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var dateConverter = { 3 | fromJson: function (data) { 4 | return new Date(data); 5 | }, 6 | toJson: function (data) { 7 | return 'some-date'; 8 | } 9 | }; 10 | Object.defineProperty(exports, "__esModule", { value: true }); 11 | exports.default = dateConverter; 12 | //# sourceMappingURL=dateconverter.js.map -------------------------------------------------------------------------------- /bower_components/mocha/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mocha", 3 | "version": "1.12.0", 4 | "main": "mocha.js", 5 | "ignore": [ 6 | "bin", 7 | "editors", 8 | "images", 9 | "lib", 10 | "support", 11 | "test", 12 | ".gitignore", 13 | ".npmignore", 14 | ".travis.yml", 15 | "component.json", 16 | "index.js", 17 | "Makefile", 18 | "package.json" 19 | ] 20 | } -------------------------------------------------------------------------------- /libs/utils.ts: -------------------------------------------------------------------------------- 1 | export function isTargetType(val:any, type:"object" | "string"):boolean { 2 | return typeof val === type; 3 | } 4 | 5 | export function isPrimitiveOrPrimitiveClass(obj:any):boolean { 6 | return !!(['string', 'boolean', 'number'].indexOf((typeof obj)) > -1 || (obj instanceof String || obj === String || 7 | obj instanceof Number || obj === Number || 8 | obj instanceof Boolean || obj === Boolean)); 9 | } 10 | 11 | export function isArrayOrArrayClass(clazz:Function):boolean { 12 | if (clazz === Array) { 13 | return true; 14 | } 15 | return Object.prototype.toString.call(clazz) === '[object Array]' 16 | } 17 | -------------------------------------------------------------------------------- /bower_components/chai/bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chai" 3 | , "version": "1.8.1" 4 | , "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic." 5 | , "license": "MIT" 6 | , "keywords": [ 7 | "test" 8 | , "assertion" 9 | , "assert" 10 | , "testing" 11 | , "chai" 12 | ] 13 | , "main": "chai.js" 14 | , "ignore": [ 15 | "build" 16 | , "components" 17 | , "lib" 18 | , "node_modules" 19 | , "support" 20 | , "test" 21 | , "index.js" 22 | , "Makefile" 23 | , ".*" 24 | ] 25 | , "dependencies": {} 26 | , "devDependencies": {} 27 | } 28 | -------------------------------------------------------------------------------- /bower_components/mocha/media/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | 7 | mocha 8 | 9 | -------------------------------------------------------------------------------- /bower_components/chai/karma.conf.js: -------------------------------------------------------------------------------- 1 | module.exports = function(config) { 2 | config.set({ 3 | basePath: '' 4 | , frameworks: [ 'mocha' ] 5 | , files: [ 6 | 'build/build.js' 7 | , 'test/bootstrap/karma.js' 8 | , 'test/*.js' 9 | ] 10 | , exclude: [] 11 | , reporters: [ 'progress' ] 12 | , port: 9876 13 | , colors: true 14 | , logLevel: config.LOG_INFO 15 | , autoWatch: false 16 | , browsers: [ 'PhantomJS' ] 17 | , captureTimeout: 60000 18 | , singleRun: true 19 | }); 20 | 21 | switch (process.env.CHAI_TEST_ENV) { 22 | case 'sauce': 23 | require('./karma.sauce')(config); 24 | break; 25 | default: 26 | // ... 27 | break; 28 | }; 29 | }; 30 | -------------------------------------------------------------------------------- /bower_components/mocha/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "mocha", 3 | "version": "1.14.0", 4 | "main": "mocha.js", 5 | "ignore": [ 6 | "bin", 7 | "editors", 8 | "images", 9 | "lib", 10 | "support", 11 | "test", 12 | ".gitignore", 13 | ".npmignore", 14 | ".travis.yml", 15 | "component.json", 16 | "index.js", 17 | "Makefile", 18 | "package.json" 19 | ], 20 | "homepage": "https://github.com/mochajs/mocha", 21 | "_release": "1.14.0", 22 | "_resolution": { 23 | "type": "version", 24 | "tag": "1.14.0", 25 | "commit": "10c65f379c4501269c83a719a04bd2fb0013f853" 26 | }, 27 | "_source": "https://github.com/mochajs/mocha.git", 28 | "_target": "~1.14.0", 29 | "_originalSource": "mocha" 30 | } -------------------------------------------------------------------------------- /libs/utils.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | function isTargetType(val, type) { 3 | return typeof val === type; 4 | } 5 | exports.isTargetType = isTargetType; 6 | function isPrimitiveOrPrimitiveClass(obj) { 7 | return !!(['string', 'boolean', 'number'].indexOf((typeof obj)) > -1 || (obj instanceof String || obj === String || 8 | obj instanceof Number || obj === Number || 9 | obj instanceof Boolean || obj === Boolean)); 10 | } 11 | exports.isPrimitiveOrPrimitiveClass = isPrimitiveOrPrimitiveClass; 12 | function isArrayOrArrayClass(clazz) { 13 | if (clazz === Array) { 14 | return true; 15 | } 16 | return Object.prototype.toString.call(clazz) === '[object Array]'; 17 | } 18 | exports.isArrayOrArrayClass = isArrayOrArrayClass; 19 | //# sourceMappingURL=utils.js.map -------------------------------------------------------------------------------- /bower_components/chai/.bower.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chai", 3 | "version": "1.8.1", 4 | "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", 5 | "license": "MIT", 6 | "keywords": [ 7 | "test", 8 | "assertion", 9 | "assert", 10 | "testing", 11 | "chai" 12 | ], 13 | "main": "chai.js", 14 | "ignore": [ 15 | "build", 16 | "components", 17 | "lib", 18 | "node_modules", 19 | "support", 20 | "test", 21 | "index.js", 22 | "Makefile", 23 | ".*" 24 | ], 25 | "dependencies": {}, 26 | "devDependencies": {}, 27 | "homepage": "https://github.com/chaijs/chai", 28 | "_release": "1.8.1", 29 | "_resolution": { 30 | "type": "version", 31 | "tag": "1.8.1", 32 | "commit": "4107c02cb1507c8554177aeeefd9732abcfd4e64" 33 | }, 34 | "_source": "https://github.com/chaijs/chai.git", 35 | "_target": "~1.8.0", 36 | "_originalSource": "chai" 37 | } -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Ailun She 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /bower_components/mocha/LICENSE: -------------------------------------------------------------------------------- 1 | (The MIT License) 2 | 3 | Copyright (c) 2011-2013 TJ Holowaychuk 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining 6 | a copy of this software and associated documentation files (the 7 | 'Software'), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to 10 | permit persons to whom the Software is furnished to do so, subject to 11 | the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be 14 | included in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 17 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 19 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 20 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 21 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 22 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /bower_components/chai/karma.sauce.js: -------------------------------------------------------------------------------- 1 | var version = require('./package.json').version; 2 | var ts = new Date().getTime(); 3 | 4 | module.exports = function(config) { 5 | var auth; 6 | 7 | try { 8 | auth = require('./test/auth/index'); 9 | } catch(ex) { 10 | auth = {}; 11 | auth.SAUCE_USERNAME = process.env.SAUCE_USERNAME || null; 12 | auth.SAUCE_ACCESS_KEY = process.env.SAUCE_ACCESS_KEY || null; 13 | } 14 | 15 | if (!auth.SAUCE_USERNAME || !auth.SAUCE_ACCESS_KEY) return; 16 | if (process.env.SKIP_SAUCE) return; 17 | 18 | var branch = process.env.TRAVIS_BRANCH || 'local' 19 | var browserConfig = require('./sauce.browsers'); 20 | var browsers = Object.keys(browserConfig); 21 | var tags = [ 'chaijs_' + version, auth.SAUCE_USERNAME + '@' + branch ]; 22 | var tunnel = process.env.TRAVIS_JOB_NUMBER || ts; 23 | 24 | if (process.env.TRAVIS_JOB_NUMBER) { 25 | tags.push('travis@' + process.env.TRAVIS_JOB_NUMBER); 26 | } 27 | 28 | config.browsers = config.browsers.concat(browsers); 29 | config.customLaunchers = browserConfig; 30 | config.reporters.push('saucelabs'); 31 | config.transports = [ 'xhr-polling' ]; 32 | 33 | config.sauceLabs = { 34 | username: auth.SAUCE_USERNAME 35 | , accessKey: auth.SAUCE_ACCESS_KEY 36 | , startConnect: true 37 | , tags: tags 38 | , testName: 'ChaiJS' 39 | , tunnelIdentifier: tunnel 40 | }; 41 | }; 42 | -------------------------------------------------------------------------------- /bower_components/chai/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "author": "Jake Luer ", 3 | "name": "chai", 4 | "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic.", 5 | "keywords": [ "test", "assertion", "assert", "testing", "chai" ], 6 | "homepage": "http://chaijs.com", 7 | "license": "MIT", 8 | "contributors": [ 9 | "Jake Luer ", 10 | "Domenic Denicola (http://domenicdenicola.com)", 11 | "Veselin Todorov ", 12 | "John Firebaugh " 13 | ], 14 | "version": "1.8.1", 15 | "repository": { 16 | "type": "git", 17 | "url": "https://github.com/chaijs/chai" 18 | }, 19 | "bugs": { 20 | "url": "https://github.com/chaijs/chai/issues" 21 | }, 22 | "main": "./index", 23 | "scripts": { 24 | "test": "make test" 25 | }, 26 | "engines": { 27 | "node": ">= 0.4.0" 28 | }, 29 | "dependencies": { 30 | "assertion-error": "1.0.0" 31 | , "deep-eql": "0.1.3" 32 | }, 33 | "devDependencies": { 34 | "component": "*" 35 | , "coveralls": "2.0.16" 36 | , "jscoverage": "0.3.7" 37 | , "karma": "canary" 38 | , "karma-mocha": "*" 39 | , "karma-sauce-launcher": "git://github.com/embarkmobile/karma-sauce-launcher.git#feature-passfail" 40 | , "mocha": "1.8.2" 41 | , "mocha-lcov-reporter": "0.0.1" 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "json-typescript-mapper", 3 | "version": "1.1.3", 4 | "typescript": { 5 | "definition": "index.d.ts" 6 | }, 7 | "dependencies": { 8 | "reflect-metadata": "^0.1.3" 9 | }, 10 | "devDependencies": { 11 | "chai": "~1.8.0", 12 | "mocha": "2.0.1" 13 | }, 14 | "scripts": { 15 | "test": "mocha ./spec/*.js", 16 | "typings:generate": "tsc --declaration" 17 | }, 18 | "description": "For single page application, data sources are obtained from API server. Instead of directly using api data, we \r definitely require an adapter layer to transform data as needed. Furthermore, \r the adapter inverse the the data dependency from API server(API Server is considered uncontrollable and \r highly unreliable as data structure may be edit by backend coder for some specific purposes)to our adapter \r which becomes reliable. Thus, this library is created as the adapter make use of es7 reflect decorator.", 19 | "main": "index.js", 20 | "repository": { 21 | "type": "git", 22 | "url": "git+https://github.com/jf3096/json-typescript-mapper.git" 23 | }, 24 | "keywords": [ 25 | "json-mapper", 26 | "typescript-json", 27 | "json-adapter", 28 | "json-transformer", 29 | "api-mapper", 30 | "api-adapter" 31 | ], 32 | "author": "Ailun She", 33 | "license": "ISC", 34 | "bugs": { 35 | "url": "https://github.com/jf3096/json-typescript-mapper/issues" 36 | }, 37 | "homepage": "https://github.com/jf3096/json-typescript-mapper#readme" 38 | } 39 | -------------------------------------------------------------------------------- /bower_components/chai/component.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "chai" 3 | , "repo": "chaijs/chai" 4 | , "version": "1.8.1" 5 | , "description": "BDD/TDD assertion library for node.js and the browser. Test framework agnostic." 6 | , "license": "MIT" 7 | , "keywords": [ 8 | "test" 9 | , "assertion" 10 | , "assert" 11 | , "testing" 12 | , "chai" 13 | ] 14 | , "main": "index.js" 15 | , "scripts": [ 16 | "index.js" 17 | , "lib/chai.js" 18 | , "lib/chai/assertion.js" 19 | , "lib/chai/core/assertions.js" 20 | , "lib/chai/interface/assert.js" 21 | , "lib/chai/interface/expect.js" 22 | , "lib/chai/interface/should.js" 23 | , "lib/chai/utils/addChainableMethod.js" 24 | , "lib/chai/utils/addMethod.js" 25 | , "lib/chai/utils/addProperty.js" 26 | , "lib/chai/utils/flag.js" 27 | , "lib/chai/utils/getActual.js" 28 | , "lib/chai/utils/getEnumerableProperties.js" 29 | , "lib/chai/utils/getMessage.js" 30 | , "lib/chai/utils/getName.js" 31 | , "lib/chai/utils/getPathValue.js" 32 | , "lib/chai/utils/getProperties.js" 33 | , "lib/chai/utils/index.js" 34 | , "lib/chai/utils/inspect.js" 35 | , "lib/chai/utils/objDisplay.js" 36 | , "lib/chai/utils/overwriteMethod.js" 37 | , "lib/chai/utils/overwriteProperty.js" 38 | , "lib/chai/utils/test.js" 39 | , "lib/chai/utils/transferFlags.js" 40 | , "lib/chai/utils/type.js" 41 | ] 42 | , "dependencies": { 43 | "chaijs/assertion-error": "1.0.0" 44 | , "chaijs/deep-eql": "0.1.3" 45 | } 46 | , "development": {} 47 | } 48 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | /** 3 | * provide interface to indicate the object is allowed to be traversed 4 | * 5 | * @interface 6 | */ 7 | export interface IGenericObject { 8 | [key: string]: any; 9 | } 10 | /** 11 | * When custom mapping of a property is required. 12 | * 13 | * @interface 14 | */ 15 | export interface ICustomConverter { 16 | fromJson(data: any): any; 17 | toJson(data: any): any; 18 | } 19 | /** 20 | * IDecoratorMetaData 21 | * DecoratorConstraint 22 | * 23 | * @interface 24 | * @property {ICustomConverter} customConverter, will be used for mapping the property, if specified 25 | * @property {boolean} excludeToJson, will exclude the property for serialization, if true 26 | */ 27 | export interface IDecoratorMetaData { 28 | name?: string; 29 | clazz?: { 30 | new (): T; 31 | }; 32 | customConverter?: ICustomConverter; 33 | excludeToJson?: boolean; 34 | } 35 | /** 36 | * JsonProperty 37 | * 38 | * @function 39 | * @property {IDecoratorMetaData|string} metadata, encapsulate it to DecoratorMetaData for standard use 40 | * @return {(target:Object, targetKey:string | symbol)=> void} decorator function 41 | */ 42 | export declare function JsonProperty(metadata?: IDecoratorMetaData | string): (target: Object, targetKey: string | symbol) => void; 43 | /** 44 | * deserialize 45 | * 46 | * @function 47 | * @param {{new():T}} clazz, class type which is going to initialize and hold a mapping json 48 | * @param {Object} json, input json object which to be mapped 49 | * 50 | * @return {T} return mapped object 51 | */ 52 | export declare function deserialize(Clazz: { 53 | new (): T; 54 | }, json: IGenericObject): T; 55 | /** 56 | * Serialize: Creates a ready-for-json-serialization object from the provided model instance. 57 | * Only @JsonProperty decorated properties in the model instance are processed. 58 | * 59 | * @param instance an instance of a model class 60 | * @returns {any} an object ready to be serialized to JSON 61 | */ 62 | export declare function serialize(instance: any): any; 63 | -------------------------------------------------------------------------------- /bower_components/chai/sauce.browsers.js: -------------------------------------------------------------------------------- 1 | 2 | /*! 3 | * Chrome 4 | */ 5 | 6 | exports['SL_Chrome'] = { 7 | base: 'SauceLabs' 8 | , browserName: 'chrome' 9 | }; 10 | 11 | /*! 12 | * Firefox 13 | */ 14 | 15 | /*! 16 | * TODO: Karma doesn't seem to like this, though sauce boots its up 17 | * 18 | 19 | exports['SL_Firefox_23'] = { 20 | base: 'SauceLabs' 21 | , browserName: 'firefox' 22 | , platform: 'Windows XP' 23 | , version: '23' 24 | }; 25 | 26 | */ 27 | 28 | exports['SL_Firefox_22'] = { 29 | base: 'SauceLabs' 30 | , browserName: 'firefox' 31 | , platform: 'Windows 7' 32 | , version: '22' 33 | }; 34 | 35 | /*! 36 | * Opera 37 | */ 38 | 39 | exports['SL_Opera_12'] = { 40 | base: 'SauceLabs' 41 | , browserName: 'opera' 42 | , platform: 'Windows 7' 43 | , version: '12' 44 | }; 45 | 46 | exports['SL_Opera_11'] = { 47 | base: 'SauceLabs' 48 | , browserName: 'opera' 49 | , platform: 'Windows 7' 50 | , version: '11' 51 | }; 52 | 53 | /*! 54 | * Internet Explorer 55 | */ 56 | 57 | exports['SL_IE_10'] = { 58 | base: 'SauceLabs' 59 | , browserName: 'internet explorer' 60 | , platform: 'Windows 2012' 61 | , version: '10' 62 | }; 63 | 64 | /*! 65 | * Safari 66 | */ 67 | 68 | exports['SL_Safari_6'] = { 69 | base: 'SauceLabs' 70 | , browserName: 'safari' 71 | , platform: 'Mac 10.8' 72 | , version: '6' 73 | }; 74 | 75 | exports['SL_Safari_5'] = { 76 | base: 'SauceLabs' 77 | , browserName: 'safari' 78 | , platform: 'Mac 10.6' 79 | , version: '5' 80 | }; 81 | 82 | /*! 83 | * iPhone 84 | */ 85 | 86 | /*! 87 | * TODO: These take forever to boot or shut down. Causes timeout. 88 | * 89 | 90 | exports['SL_iPhone_6'] = { 91 | base: 'SauceLabs' 92 | , browserName: 'iphone' 93 | , platform: 'Mac 10.8' 94 | , version: '6' 95 | }; 96 | 97 | exports['SL_iPhone_5-1'] = { 98 | base: 'SauceLabs' 99 | , browserName: 'iphone' 100 | , platform: 'Mac 10.8' 101 | , version: '5.1' 102 | }; 103 | 104 | exports['SL_iPhone_5'] = { 105 | base: 'SauceLabs' 106 | , browserName: 'iphone' 107 | , platform: 'Mac 10.6' 108 | , version: '5' 109 | }; 110 | 111 | */ 112 | 113 | /*! 114 | * Android 115 | */ 116 | 117 | /*! 118 | * TODO: fails because of error serialization 119 | * 120 | 121 | exports['SL_Android_4'] = { 122 | base: 'SauceLabs' 123 | , browserName: 'android' 124 | , platform: 'Linux' 125 | , version: '4' 126 | }; 127 | 128 | */ 129 | -------------------------------------------------------------------------------- /bower_components/chai/README.md: -------------------------------------------------------------------------------- 1 | [![Chai Documentation](http://chaijs.com/public/img/chai-logo.png)](http://chaijs.com) 2 | 3 | Chai is a BDD / TDD assertion library for [node](http://nodejs.org) and the browser that 4 | can be delightfully paired with any javascript testing framework. 5 | 6 | For more information or to download plugins, view the [documentation](http://chaijs.com). 7 | 8 | [![Build Status](https://travis-ci.org/chaijs/chai.png?branch=master)](https://travis-ci.org/chaijs/chai) [![Coverage Status](https://coveralls.io/repos/chaijs/chai/badge.png?branch=master)](https://coveralls.io/r/chaijs/chai?branch=master) 9 | 10 | [![Selenium Test Status](https://saucelabs.com/browser-matrix/chaijs.svg)](https://saucelabs.com/u/chaijs) 11 | 12 | ### Related Projects 13 | 14 | - [chaijs / assertion-error](https://github.com/chaijs/assertion-error): Custom `Error` constructor thrown upon an assertion failing. 15 | - [chaijs / deep-eql](https://github.com/chaijs/deep-eql): Improved deep equality testing for Node.js and the browser. 16 | 17 | ### Contributors 18 | 19 | project : chai 20 | repo age : 1 year, 9 months 21 | active : 139 days 22 | commits : 693 23 | files : 54 24 | authors : 25 | 518 Jake Luer 74.7% 26 | 66 Veselin Todorov 9.5% 27 | 43 Domenic Denicola 6.2% 28 | 6 Ruben Verborgh 0.9% 29 | 5 George Kats 0.7% 30 | 5 Jo Liss 0.7% 31 | 5 Juliusz Gonera 0.7% 32 | 5 Scott Nonnenberg 0.7% 33 | 4 John Firebaugh 0.6% 34 | 4 Nick Heiner 0.6% 35 | 4 josher19 0.6% 36 | 3 Jeff Barczewski 0.4% 37 | 3 Ryunosuke SATO 0.4% 38 | 2 Bartvds 0.3% 39 | 2 Edwin Shao 0.3% 40 | 2 Jakub Nešetřil 0.3% 41 | 2 Teddy Cross 0.3% 42 | 1 Anand Patil 0.1% 43 | 1 Benjamin Horsleben 0.1% 44 | 1 Brandon Payton 0.1% 45 | 1 Chris Connelly 0.1% 46 | 1 Chun-Yi 0.1% 47 | 1 DD 0.1% 48 | 1 Jeff Welch 0.1% 49 | 1 Kilian Ciuffolo 0.1% 50 | 1 Niklas Närhinen 0.1% 51 | 1 Paul Miller 0.1% 52 | 1 Sasha Koss 0.1% 53 | 1 Victor Costan 0.1% 54 | 1 Vinay Pulim 0.1% 55 | 1 piecioshka 0.1% 56 | 57 | ## License 58 | 59 | (The MIT License) 60 | 61 | Copyright (c) 2011-2013 Jake Luer 62 | 63 | Permission is hereby granted, free of charge, to any person obtaining a copy 64 | of this software and associated documentation files (the "Software"), to deal 65 | in the Software without restriction, including without limitation the rights 66 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 67 | copies of the Software, and to permit persons to whom the Software is 68 | furnished to do so, subject to the following conditions: 69 | 70 | The above copyright notice and this permission notice shall be included in 71 | all copies or substantial portions of the Software. 72 | 73 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 74 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 75 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 76 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 77 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 78 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 79 | THE SOFTWARE. 80 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # json-typescript-mapper 2 | 3 | ## Introduction 4 | 5 | For single page application, data sources are obtained from API server. Instead of directly using api data, we 6 | definitely require an adapter layer to transform data as needed. Furthermore, 7 | the adapter inverse the the data dependency from API server(API Server is considered uncontrollable and 8 | highly unreliable as data structure may be edit by backend coder for some specific purposes)to our adapter 9 | which becomes reliable. Thus, this library is created as the adapter. 10 | 11 | ### Get Started 12 | ```bash 13 | npm install json-typescript-mapper --save 14 | ``` 15 | ## Environment 16 | * NodeJS 17 | * Browser 18 | 19 | ## Language 20 | * Typescript 21 | 22 | ### Typescript 23 | 24 | ```bash 25 | import {deserialize} from 'json-typescript-mapper'; 26 | 27 | deserialize(, ); 28 | serialize(); 29 | ``` 30 | 31 | ## Example 32 | Here is a complex example, hopefully could give you an idea of how to use it (for more on how to use, checkout /spec which are unit test cases): 33 | 34 | ```typescript 35 | class Student { 36 | @JsonProperty('name') 37 | fullName:string; 38 | 39 | constructor() { 40 | this.fullName = undefined; 41 | } 42 | } 43 | 44 | class Address { 45 | @JsonProperty('first-line') 46 | firstLine:string; 47 | @JsonProperty('second-line') 48 | secondLine:string; 49 | @JsonProperty({clazz: Student}) 50 | student:Student; 51 | city:string; 52 | 53 | constructor() { 54 | this.firstLine = undefined; 55 | this.secondLine = undefined; 56 | this.city = undefined; 57 | this.student = undefined 58 | } 59 | } 60 | 61 | class Person { 62 | @JsonProperty('Name') 63 | name:string; 64 | @JsonProperty('xing') 65 | surname:string; 66 | age:number; 67 | @JsonProperty({clazz: Address, name: 'AddressArr'}) 68 | addressArr:Address[]; 69 | @JsonProperty({clazz: Address, name: 'Address'}) 70 | address:Address; 71 | 72 | constructor() { 73 | this.name = void 0; 74 | this.surname = void 0; 75 | this.age = void 0; 76 | this.addressArr = void 0; 77 | this.address = void 0; 78 | } 79 | } 80 | ``` 81 | 82 | Now here is what API server return, assume it is already parsed to JSON object. 83 | ```typescript 84 | let json = { 85 | "Name": "Mark", 86 | "xing": "Galea", 87 | "age": 30, 88 | "AddressArr": [ 89 | { 90 | "first-line": "Some where", 91 | "second-line": "Over Here", 92 | "city": "In This City", 93 | "student": { 94 | name1: "Ailun" 95 | } 96 | }, 97 | { 98 | "first-line": "Some where", 99 | "second-line": "Over Here", 100 | "city": "In This City", 101 | "student": { 102 | name1: "Ailun" 103 | } 104 | } 105 | ], 106 | "Address": { 107 | "first-line": "Some where", 108 | "second-line": "Over Here", 109 | "city": "In This City", 110 | "student": { 111 | name: "Ailun" 112 | } 113 | } 114 | ``` 115 | 116 | Simply, just map it use following code. The mapping is based on <@JsonProperty> decorator meta data. 117 | 118 | ```typescript 119 | const person = deserialize(Person, json); 120 | ``` 121 | 122 | If you want to reverse the action, from the other way round: 123 | 124 | ```typescript 125 | const json = serialize(person); 126 | ``` 127 | 128 | ## Notice 129 | Remember to add: experimentalDecorators and emitDecoratorMetadata in your tsconfig.json. 130 | This is essential to enable decorator support for your typescript program. Example shown as followings: 131 | 132 | ```json 133 | { 134 | "compilerOptions": { 135 | "module": "commonjs", 136 | "target": "es5", 137 | "sourceMap": true, 138 | "experimentalDecorators": true, 139 | "emitDecoratorMetadata": true 140 | }, 141 | "exclude": [ 142 | "node_modules" 143 | ] 144 | } 145 | ``` 146 | ## Test Report 147 | The test case will be covered in the next push. This caused by inconsistent return type. 148 | ![alt tag](/git-img/Test Results — spec_index.ts.png) 149 | 150 | ## Fixed 151 | 1) Fixed test cases. According to typescript official website tips [NULL IS BAD](https://basarat.gitbooks.io/typescript/content/docs/tips/null.html), 152 | therefore I updated all null value to void 0 which is a better expression than undefined (idea from underscore source code). 153 | Most cases it won't affect previous version at all. 154 | 155 | ## Contributor 156 | [@dankmo](https://github.com/dankmo) 157 | 158 | ## ChangeLog 159 | #### 2017-02-20 160 | 161 | **json-typescript-mapper** 1.1.1 162 | - Added serialized function 163 | - Passed more unit tests 164 | -------------------------------------------------------------------------------- /bower_components/mocha/Readme.md: -------------------------------------------------------------------------------- 1 | [![Build Status](https://secure.travis-ci.org/visionmedia/mocha.png)](http://travis-ci.org/visionmedia/mocha) 2 | 3 | [![Mocha test framework](http://f.cl.ly/items/3l1k0n2A1U3M1I1L210p/Screen%20Shot%202012-02-24%20at%202.21.43%20PM.png)](http://visionmedia.github.io/mocha) 4 | 5 | Mocha is a simple, flexible, fun JavaScript test framework for node.js and the browser. For more information view the [documentation](http://visionmedia.github.io/mocha). 6 | 7 | ## Contributors 8 | 9 | ``` 10 | 11 | project : mocha 12 | repo age : 1 year, 7 months 13 | active : 272 days 14 | commits : 1116 15 | files : 123 16 | authors : 17 | 504 TJ Holowaychuk 45.2% 18 | 389 Tj Holowaychuk 34.9% 19 | 31 Guillermo Rauch 2.8% 20 | 13 Attila Domokos 1.2% 21 | 9 John Firebaugh 0.8% 22 | 8 Jo Liss 0.7% 23 | 7 Nathan Rajlich 0.6% 24 | 6 James Carr 0.5% 25 | 6 Brendan Nee 0.5% 26 | 5 Aaron Heckmann 0.4% 27 | 4 hokaccha 0.4% 28 | 4 Xavier Antoviaque 0.4% 29 | 4 Joshua Krall 0.4% 30 | 3 Wil Moore III 0.3% 31 | 3 Jesse Dailey 0.3% 32 | 3 Nathan Bowser 0.3% 33 | 3 Tyson Tate 0.3% 34 | 3 Cory Thomas 0.3% 35 | 3 Ryunosuke SATO 0.3% 36 | 3 Paul Miller 0.3% 37 | 3 Ben Lindsey 0.3% 38 | 2 Forbes Lindesay 0.2% 39 | 2 Konstantin Käfer 0.2% 40 | 2 Brian Beck 0.2% 41 | 2 Merrick Christensen 0.2% 42 | 2 Michael Riley 0.2% 43 | 2 David Henderson 0.2% 44 | 2 Nathan Alderson 0.2% 45 | 2 Paul Armstrong 0.2% 46 | 2 Pete Hawkins 0.2% 47 | 2 Quang Van 0.2% 48 | 2 Raynos 0.2% 49 | 2 Jonas Westerlund 0.2% 50 | 2 Domenic Denicola 0.2% 51 | 2 Shawn Krisman 0.2% 52 | 2 Simon Gaeremynck 0.2% 53 | 2 FARKAS Máté 0.2% 54 | 2 Timo Tijhof 0.2% 55 | 2 Justin DuJardin 0.2% 56 | 2 Juzer Ali 0.2% 57 | 2 Ian Storm Taylor 0.2% 58 | 2 Arian Stolwijk 0.2% 59 | 2 domenic 0.2% 60 | 1 Richard Dingwall 0.1% 61 | 1 Russ Bradberry 0.1% 62 | 1 Sasha Koss 0.1% 63 | 1 Seiya Konno 0.1% 64 | 1 Standa Opichal 0.1% 65 | 1 Steve Mason 0.1% 66 | 1 Will Langstroth 0.1% 67 | 1 Yanis Wang 0.1% 68 | 1 Yuest Wang 0.1% 69 | 1 abrkn 0.1% 70 | 1 airportyh 0.1% 71 | 1 fengmk2 0.1% 72 | 1 tgautier@yahoo.com 0.1% 73 | 1 traleig1 0.1% 74 | 1 vlad 0.1% 75 | 1 yuitest 0.1% 76 | 1 Adam Crabtree 0.1% 77 | 1 Andreas Brekken 0.1% 78 | 1 Atsuya Takagi 0.1% 79 | 1 Austin Birch 0.1% 80 | 1 Bjørge Næss 0.1% 81 | 1 Brian Moore 0.1% 82 | 1 Bryan Donovan 0.1% 83 | 1 Casey Foster 0.1% 84 | 1 Corey Butler 0.1% 85 | 1 Dave McKenna 0.1% 86 | 1 Fedor Indutny 0.1% 87 | 1 Florian Margaine 0.1% 88 | 1 Frederico Silva 0.1% 89 | 1 Fredrik Lindin 0.1% 90 | 1 Gareth Murphy 0.1% 91 | 1 Gavin Mogan 0.1% 92 | 1 Greg Perkins 0.1% 93 | 1 Harry Brundage 0.1% 94 | 1 Herman Junge 0.1% 95 | 1 Ian Young 0.1% 96 | 1 Ivan 0.1% 97 | 1 Jaakko Salonen 0.1% 98 | 1 Jakub Nešetřil 0.1% 99 | 1 James Bowes 0.1% 100 | 1 James Lal 0.1% 101 | 1 Jason Barry 0.1% 102 | 1 Javier Aranda 0.1% 103 | 1 Jeff Kunkle 0.1% 104 | 1 Jonathan Creamer 0.1% 105 | 1 Jussi Virtanen 0.1% 106 | 1 Katie Gengler 0.1% 107 | 1 Kazuhito Hokamura 0.1% 108 | 1 Koen Punt 0.1% 109 | 1 Laszlo Bacsi 0.1% 110 | 1 László Bácsi 0.1% 111 | 1 Maciej Małecki 0.1% 112 | 1 Matt Robenolt 0.1% 113 | 1 Matt Smith 0.1% 114 | 1 Matthew Shanley 0.1% 115 | 1 Michael Schoonmaker 0.1% 116 | 1 Phil Sung 0.1% 117 | 1 R56 0.1% 118 | ``` 119 | 120 | ## Links 121 | 122 | - [Google Group](http://groups.google.com/group/mochajs) 123 | - [Wiki](https://github.com/visionmedia/mocha/wiki) 124 | - Mocha [Extensions and reporters](https://github.com/visionmedia/mocha/wiki) 125 | -------------------------------------------------------------------------------- /spec/serialize.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai'; 2 | import {serialize, JsonProperty} from '../index'; 3 | import dateConverter from './common/dateconverter'; 4 | 5 | describe('serialize', function () { 6 | 7 | it('should use the property name given in the meta data', function () { 8 | class ClassWithPrimitiveProp { 9 | @JsonProperty('theName') 10 | name: string = undefined; 11 | } 12 | const instance = new ClassWithPrimitiveProp(); 13 | instance.name = 'Jim'; 14 | const serializedInstance = serialize(instance); 15 | expect(serializedInstance.theName).to.equal('Jim'); 16 | }); 17 | 18 | describe('primitive types', function () { 19 | 20 | const primitiveTypes = ['some-string', true, 25, new Number(25), new Boolean(true)]; 21 | 22 | primitiveTypes.forEach((primitiveType) => { 23 | it(`should keep ${typeof primitiveType} as is`, function () { 24 | class PrimitiveProp { 25 | @JsonProperty('someProp') 26 | someProp = primitiveType; 27 | } 28 | const instance = new PrimitiveProp(); 29 | // instance.someProp = primitiveType; 30 | const serializedInstance = serialize(instance); 31 | expect(serializedInstance.someProp).to.equal(primitiveType); 32 | }); 33 | }); 34 | }); 35 | 36 | it('should keep unspecified objects as is', function () { 37 | class ClassWithUnspecObject { 38 | @JsonProperty('date') 39 | date: Date = new Date(); 40 | } 41 | const instance = new ClassWithUnspecObject(); 42 | const serializedInstance = serialize(instance); 43 | expect(serializedInstance.date).to.equal(instance.date); 44 | }); 45 | 46 | it('should use custom converter if available', function () { 47 | class ClassWithCustomConv { 48 | @JsonProperty({name: 'date', customConverter: dateConverter}) 49 | date: Date = new Date(); 50 | } 51 | const instance = new ClassWithCustomConv(); 52 | const serializedInstance = serialize(instance); 53 | expect(serializedInstance.date).to.equal('some-date'); 54 | }); 55 | 56 | it('should exclude properties if specified', function () { 57 | class ClassWithExcludedProp { 58 | @JsonProperty('name') 59 | name: string = 'John'; 60 | 61 | @JsonProperty({name: 'lastName', excludeToJson: true}) 62 | lastName: string = 'Doe'; 63 | } 64 | const instance = new ClassWithExcludedProp(); 65 | const serializedInstance = serialize(instance); 66 | expect(serializedInstance.name).to.equal('John'); 67 | expect(serializedInstance.lastName).to.be.undefined; 68 | }); 69 | 70 | it('should work recursively if clazz is specified in meta data', function () { 71 | class OtherClass { 72 | @JsonProperty({name: 'date', customConverter: dateConverter}) 73 | date: Date = new Date(); 74 | } 75 | class ClassWithClassProp { 76 | @JsonProperty({name: 'other', clazz: OtherClass}) 77 | other: OtherClass = new OtherClass(); 78 | } 79 | const instance = new ClassWithClassProp(); 80 | const serializedInstance = serialize(instance); 81 | expect(serializedInstance.other.date).to.equal('some-date'); 82 | }); 83 | 84 | describe('Arrays', () => { 85 | it('should keep as is if no clazz is specified', function () { 86 | class ClassWithArrayProp { 87 | @JsonProperty('items') 88 | items: Array = [new Date(), new Date()]; 89 | } 90 | const instance = new ClassWithArrayProp(); 91 | const serializedInstance = serialize(instance); 92 | expect(serializedInstance.items).to.be.instanceof(Array); 93 | expect(serializedInstance.items.length).to.equal(2); 94 | expect(serializedInstance.items[0]).to.equal(instance.items[0]); 95 | expect(serializedInstance.items[1]).to.equal(instance.items[1]); 96 | }); 97 | 98 | it('should apply serialize for all array items if clazz is specified', function () { 99 | class OtherClass { 100 | @JsonProperty({name: 'date', customConverter: dateConverter}) 101 | date: Date = new Date(); 102 | } 103 | class ClassWithArrayProp { 104 | @JsonProperty({name: 'items', clazz: OtherClass}) 105 | items: Array = [new OtherClass(), new OtherClass()]; 106 | } 107 | const instance = new ClassWithArrayProp(); 108 | const serializedInstance = serialize(instance); 109 | expect(serializedInstance.items).to.be.instanceof(Array); 110 | expect(serializedInstance.items.length).to.equal(2); 111 | expect(serializedInstance.items[0].date).to.equal('some-date'); 112 | expect(serializedInstance.items[1].date).to.equal('some-date'); 113 | }); 114 | }); 115 | }); -------------------------------------------------------------------------------- /bower_components/mocha/mocha.css: -------------------------------------------------------------------------------- 1 | @charset "utf-8"; 2 | 3 | body { 4 | margin:0; 5 | } 6 | 7 | #mocha { 8 | font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif; 9 | margin: 60px 50px; 10 | } 11 | 12 | #mocha ul, #mocha li { 13 | margin: 0; 14 | padding: 0; 15 | } 16 | 17 | #mocha ul { 18 | list-style: none; 19 | } 20 | 21 | #mocha h1, #mocha h2 { 22 | margin: 0; 23 | } 24 | 25 | #mocha h1 { 26 | margin-top: 15px; 27 | font-size: 1em; 28 | font-weight: 200; 29 | } 30 | 31 | #mocha h1 a { 32 | text-decoration: none; 33 | color: inherit; 34 | } 35 | 36 | #mocha h1 a:hover { 37 | text-decoration: underline; 38 | } 39 | 40 | #mocha .suite .suite h1 { 41 | margin-top: 0; 42 | font-size: .8em; 43 | } 44 | 45 | #mocha .hidden { 46 | display: none; 47 | } 48 | 49 | #mocha h2 { 50 | font-size: 12px; 51 | font-weight: normal; 52 | cursor: pointer; 53 | } 54 | 55 | #mocha .suite { 56 | margin-left: 15px; 57 | } 58 | 59 | #mocha .test { 60 | margin-left: 15px; 61 | overflow: hidden; 62 | } 63 | 64 | #mocha .test.pending:hover h2::after { 65 | content: '(pending)'; 66 | font-family: arial, sans-serif; 67 | } 68 | 69 | #mocha .test.pass.medium .duration { 70 | background: #C09853; 71 | } 72 | 73 | #mocha .test.pass.slow .duration { 74 | background: #B94A48; 75 | } 76 | 77 | #mocha .test.pass::before { 78 | content: '✓'; 79 | font-size: 12px; 80 | display: block; 81 | float: left; 82 | margin-right: 5px; 83 | color: #00d6b2; 84 | } 85 | 86 | #mocha .test.pass .duration { 87 | font-size: 9px; 88 | margin-left: 5px; 89 | padding: 2px 5px; 90 | color: white; 91 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); 92 | -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2); 93 | box-shadow: inset 0 1px 1px rgba(0,0,0,.2); 94 | -webkit-border-radius: 5px; 95 | -moz-border-radius: 5px; 96 | -ms-border-radius: 5px; 97 | -o-border-radius: 5px; 98 | border-radius: 5px; 99 | } 100 | 101 | #mocha .test.pass.fast .duration { 102 | display: none; 103 | } 104 | 105 | #mocha .test.pending { 106 | color: #0b97c4; 107 | } 108 | 109 | #mocha .test.pending::before { 110 | content: '◦'; 111 | color: #0b97c4; 112 | } 113 | 114 | #mocha .test.fail { 115 | color: #c00; 116 | } 117 | 118 | #mocha .test.fail pre { 119 | color: black; 120 | } 121 | 122 | #mocha .test.fail::before { 123 | content: '✖'; 124 | font-size: 12px; 125 | display: block; 126 | float: left; 127 | margin-right: 5px; 128 | color: #c00; 129 | } 130 | 131 | #mocha .test pre.error { 132 | color: #c00; 133 | max-height: 300px; 134 | overflow: auto; 135 | } 136 | 137 | #mocha .test pre { 138 | display: block; 139 | float: left; 140 | clear: left; 141 | font: 12px/1.5 monaco, monospace; 142 | margin: 5px; 143 | padding: 15px; 144 | border: 1px solid #eee; 145 | border-bottom-color: #ddd; 146 | -webkit-border-radius: 3px; 147 | -webkit-box-shadow: 0 1px 3px #eee; 148 | -moz-border-radius: 3px; 149 | -moz-box-shadow: 0 1px 3px #eee; 150 | border-radius: 3px; 151 | } 152 | 153 | #mocha .test h2 { 154 | position: relative; 155 | } 156 | 157 | #mocha .test a.replay { 158 | position: absolute; 159 | top: 3px; 160 | right: 0; 161 | text-decoration: none; 162 | vertical-align: middle; 163 | display: block; 164 | width: 15px; 165 | height: 15px; 166 | line-height: 15px; 167 | text-align: center; 168 | background: #eee; 169 | font-size: 15px; 170 | -moz-border-radius: 15px; 171 | border-radius: 15px; 172 | -webkit-transition: opacity 200ms; 173 | -moz-transition: opacity 200ms; 174 | transition: opacity 200ms; 175 | opacity: 0.3; 176 | color: #888; 177 | } 178 | 179 | #mocha .test:hover a.replay { 180 | opacity: 1; 181 | } 182 | 183 | #mocha-report.pass .test.fail { 184 | display: none; 185 | } 186 | 187 | #mocha-report.fail .test.pass { 188 | display: none; 189 | } 190 | 191 | #mocha-report.pending .test.pass, 192 | #mocha-report.pending .test.fail { 193 | display: none; 194 | } 195 | #mocha-report.pending .test.pass.pending { 196 | display: block; 197 | } 198 | 199 | #mocha-error { 200 | color: #c00; 201 | font-size: 1.5em; 202 | font-weight: 100; 203 | letter-spacing: 1px; 204 | } 205 | 206 | #mocha-stats { 207 | position: fixed; 208 | top: 15px; 209 | right: 10px; 210 | font-size: 12px; 211 | margin: 0; 212 | color: #888; 213 | z-index: 1; 214 | } 215 | 216 | #mocha-stats .progress { 217 | float: right; 218 | padding-top: 0; 219 | } 220 | 221 | #mocha-stats em { 222 | color: black; 223 | } 224 | 225 | #mocha-stats a { 226 | text-decoration: none; 227 | color: inherit; 228 | } 229 | 230 | #mocha-stats a:hover { 231 | border-bottom: 1px solid #eee; 232 | } 233 | 234 | #mocha-stats li { 235 | display: inline-block; 236 | margin: 0 5px; 237 | list-style: none; 238 | padding-top: 11px; 239 | } 240 | 241 | #mocha-stats canvas { 242 | width: 40px; 243 | height: 40px; 244 | } 245 | 246 | #mocha code .comment { color: #ddd } 247 | #mocha code .init { color: #2F6FAD } 248 | #mocha code .string { color: #5890AD } 249 | #mocha code .keyword { color: #8A6343 } 250 | #mocha code .number { color: #2F6FAD } 251 | 252 | @media screen and (max-device-width: 480px) { 253 | #mocha { 254 | margin: 60px 0px; 255 | } 256 | 257 | #mocha #stats { 258 | position: absolute; 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /spec/index.ts: -------------------------------------------------------------------------------- 1 | import {expect} from 'chai'; 2 | import {deserialize, JsonProperty} from '../index'; 3 | import dateConverter from './common/dateconverter' 4 | 5 | class Student { 6 | @JsonProperty('name') 7 | fullName: string; 8 | 9 | @JsonProperty({name: 'dob', customConverter: dateConverter}) 10 | dateOfBirth: Date = undefined; 11 | 12 | constructor() { 13 | this.fullName = void 0; 14 | } 15 | } 16 | 17 | class Address { 18 | @JsonProperty('first-line') 19 | firstLine: string; 20 | @JsonProperty('second-line') 21 | secondLine: string; 22 | @JsonProperty({clazz: Student}) 23 | student: Student; 24 | city: string; 25 | 26 | constructor() { 27 | this.firstLine = void 0; 28 | this.secondLine = void 0; 29 | this.city = void 0; 30 | this.student = void 0 31 | } 32 | } 33 | 34 | 35 | class Person { 36 | @JsonProperty('Name') 37 | name: string; 38 | @JsonProperty('xing') 39 | surname: string; 40 | age: number; 41 | @JsonProperty({clazz: Address, name: 'AddressArr'}) 42 | addressArr: Address[]; 43 | @JsonProperty({clazz: Address, name: 'Address'}) 44 | address: Address; 45 | 46 | constructor() { 47 | this.name = void 0; 48 | this.surname = void 0; 49 | this.age = void 0; 50 | this.addressArr = void 0; 51 | this.address = void 0; 52 | } 53 | } 54 | 55 | describe('index()', function () { 56 | it('simple json object #1', function () { 57 | let json = { 58 | "Name": "Mark", 59 | "xing": "Galea", 60 | "age": 30, 61 | "AddressArr": [] as Array, 62 | "Address": null as any 63 | }; 64 | const person = deserialize(Person, json); 65 | expect(person.address).to.be.equals(void 0); 66 | expect(person.name).to.be.equal("Mark"); 67 | expect(person.surname).to.be.equal("Galea"); 68 | expect(person.addressArr).to.be.empty; 69 | }); 70 | 71 | it('simple json object #2', function () { 72 | let addressjson = { 73 | "first-line": "Some where", 74 | "second-line": "Over Here", 75 | "city": "In This City", 76 | "student": { 77 | name: "Ailun" 78 | } 79 | }; 80 | const address = deserialize(Address, addressjson); 81 | expect(address.firstLine).to.be.equal("Some where"); 82 | expect(address.secondLine).to.be.equal("Over Here"); 83 | expect(address.city).to.be.equal("In This City"); 84 | expect(address.student).to.be.an('object'); 85 | expect(address.student.fullName).to.be.equal('Ailun'); 86 | }); 87 | 88 | it('complex json object #1', function () { 89 | let json = { 90 | "Name": "Mark", 91 | "xing": "Galea", 92 | "age": 30, 93 | "AddressArr": [ 94 | { 95 | "first-line": "Some where", 96 | "second-line": "Over Here", 97 | "city": "In This City", 98 | "student": { 99 | name1: "Ailun" 100 | } 101 | }, 102 | { 103 | "first-line": "Some where", 104 | "second-line": "Over Here", 105 | "city": "In This City", 106 | "student": { 107 | name1: "Ailun" 108 | } 109 | } 110 | ], 111 | "Address": { 112 | "first-line": "Some where", 113 | "second-line": "Over Here", 114 | "city": "In This City", 115 | "student": { 116 | name: "Ailun" 117 | } 118 | } 119 | }; 120 | const person = deserialize(Person, json); 121 | expect(person.address).to.be.an.instanceOf(Address); 122 | expect(person.age).to.be.a('number'); 123 | expect(person.name).to.be.a('string'); 124 | expect(person.address).to.be.an('object'); 125 | expect(person.addressArr.length).to.be.equals(2); 126 | expect(person.address.student.fullName).to.be.equals('Ailun'); 127 | }); 128 | 129 | it('empty json object #1', function () { 130 | let json = {}; 131 | const person = deserialize(Person, json); 132 | expect(person.address).to.be.equal(void 0); 133 | expect(person.name).to.be.equal(void 0); 134 | expect(person.surname).to.be.equal(void 0); 135 | expect(person.addressArr).to.be.equal(void 0); 136 | }); 137 | 138 | it('empty json object #2', function () { 139 | let json: any = null; 140 | const person = deserialize(Person, json); 141 | expect(person).to.be.equals(void 0); 142 | }); 143 | 144 | it('empty json object #3', function () { 145 | let json: any = void 0; 146 | const person = deserialize(Person, json); 147 | expect(person).to.be.equals(void 0); 148 | }); 149 | 150 | it('invalid primitive value #1', function () { 151 | let json = 123; 152 | const person = deserialize(Person, json as any); 153 | expect(person).to.be.equals(void 0); 154 | }); 155 | 156 | it('invalid primitive value #2', function () { 157 | let json = ''; 158 | const person = deserialize(Person, json as any); 159 | expect(person).to.be.equals(void 0); 160 | }); 161 | 162 | it('invalid primitive value #3', function () { 163 | let json = NaN; 164 | const person = deserialize(Person, json as any); 165 | expect(person).to.be.equals(void 0); 166 | }); 167 | 168 | it('invalid json object #1', function () { 169 | let json = { 170 | "NameTest": "Mark", 171 | }; 172 | const person = deserialize(Person, json); 173 | expect(person.name).to.be.equals(void 0); 174 | }); 175 | 176 | it('should use a custom converter if available', function () { 177 | const json = { 178 | "name": "John Doe", 179 | dob: "1995-11-10" 180 | }; 181 | const student = deserialize(Student, json); 182 | expect(student.fullName).to.be.equals('John Doe'); 183 | expect(student.dateOfBirth).to.be.instanceof(Date); 184 | expect(student.dateOfBirth.toString()).to.equal(new Date("1995-11-10").toString()); 185 | }); 186 | }); 187 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | require('reflect-metadata'); 3 | var utils_1 = require('./libs/utils'); 4 | /** 5 | * Decorator variable name 6 | * 7 | * @const 8 | */ 9 | var JSON_META_DATA_KEY = 'JsonProperty'; 10 | /** 11 | * DecoratorMetaData 12 | * Model used for decoration parameters 13 | * 14 | * @class 15 | * @property {string} name, indicate which json property needed to map 16 | * @property {string} clazz, if the target is not primitive type, map it to corresponding class 17 | */ 18 | var DecoratorMetaData = (function () { 19 | function DecoratorMetaData(name, clazz) { 20 | this.name = name; 21 | this.clazz = clazz; 22 | } 23 | return DecoratorMetaData; 24 | }()); 25 | /** 26 | * JsonProperty 27 | * 28 | * @function 29 | * @property {IDecoratorMetaData|string} metadata, encapsulate it to DecoratorMetaData for standard use 30 | * @return {(target:Object, targetKey:string | symbol)=> void} decorator function 31 | */ 32 | function JsonProperty(metadata) { 33 | var decoratorMetaData; 34 | if (utils_1.isTargetType(metadata, 'string')) { 35 | decoratorMetaData = new DecoratorMetaData(metadata); 36 | } 37 | else if (utils_1.isTargetType(metadata, 'object')) { 38 | decoratorMetaData = metadata; 39 | } 40 | else { 41 | throw new Error('index.ts: meta data in Json property is undefined. meta data: ' + metadata); 42 | } 43 | return Reflect.metadata(JSON_META_DATA_KEY, decoratorMetaData); 44 | } 45 | exports.JsonProperty = JsonProperty; 46 | /** 47 | * getClazz 48 | * 49 | * @function 50 | * @property {any} target object 51 | * @property {string} propertyKey, used as target property 52 | * @return {Function} Function/Class indicate the target property type 53 | * @description Used for type checking, if it is not primitive type, loop inside recursively 54 | */ 55 | function getClazz(target, propertyKey) { 56 | return Reflect.getMetadata('design:type', target, propertyKey); 57 | } 58 | /** 59 | * getJsonProperty 60 | * 61 | * @function 62 | * @property {any} target object 63 | * @property {string} propertyKey, used as target property 64 | * @return {IDecoratorMetaData} Obtain target property decorator meta data 65 | */ 66 | function getJsonProperty(target, propertyKey) { 67 | return Reflect.getMetadata(JSON_META_DATA_KEY, target, propertyKey); 68 | } 69 | /** 70 | * hasAnyNullOrUndefined 71 | * 72 | * @function 73 | * @property {...args:any[]} any arguments 74 | * @return {IDecoratorMetaData} check if any arguments is null or undefined 75 | */ 76 | function hasAnyNullOrUndefined() { 77 | var args = []; 78 | for (var _i = 0; _i < arguments.length; _i++) { 79 | args[_i - 0] = arguments[_i]; 80 | } 81 | return args.some(function (arg) { return arg === null || arg === undefined; }); 82 | } 83 | function mapFromJson(decoratorMetadata, instance, json, key) { 84 | /** 85 | * if decorator name is not found, use target property key as decorator name. It means mapping it directly 86 | */ 87 | var decoratorName = decoratorMetadata.name || key; 88 | var innerJson = json ? json[decoratorName] : undefined; 89 | var clazz = getClazz(instance, key); 90 | if (utils_1.isArrayOrArrayClass(clazz)) { 91 | var metadata_1 = getJsonProperty(instance, key); 92 | if (metadata_1 && metadata_1.clazz || utils_1.isPrimitiveOrPrimitiveClass(clazz)) { 93 | if (innerJson && utils_1.isArrayOrArrayClass(innerJson)) { 94 | return innerJson.map(function (item) { return deserialize(metadata_1.clazz, item); }); 95 | } 96 | return; 97 | } 98 | else { 99 | return innerJson; 100 | } 101 | } 102 | if (!utils_1.isPrimitiveOrPrimitiveClass(clazz)) { 103 | return deserialize(clazz, innerJson); 104 | } 105 | return json ? json[decoratorName] : undefined; 106 | } 107 | /** 108 | * deserialize 109 | * 110 | * @function 111 | * @param {{new():T}} clazz, class type which is going to initialize and hold a mapping json 112 | * @param {Object} json, input json object which to be mapped 113 | * 114 | * @return {T} return mapped object 115 | */ 116 | function deserialize(Clazz, json) { 117 | /** 118 | * As it is a recursive function, ignore any arguments that are unset 119 | */ 120 | if (hasAnyNullOrUndefined(Clazz, json)) { 121 | return void 0; 122 | } 123 | /** 124 | * Prevent non-json continue 125 | */ 126 | if (!utils_1.isTargetType(json, 'object')) { 127 | return void 0; 128 | } 129 | /** 130 | * init root class to contain json 131 | */ 132 | var instance = new Clazz(); 133 | Object.keys(instance).forEach(function (key) { 134 | /** 135 | * get decoratorMetaData, structure: { name?:string, clazz?:{ new():T } } 136 | */ 137 | var decoratorMetaData = getJsonProperty(instance, key); 138 | /** 139 | * pass value to instance 140 | */ 141 | if (decoratorMetaData && decoratorMetaData.customConverter) { 142 | instance[key] = decoratorMetaData.customConverter.fromJson(json[decoratorMetaData.name || key]); 143 | } 144 | else { 145 | instance[key] = decoratorMetaData ? mapFromJson(decoratorMetaData, instance, json, key) : json[key]; 146 | } 147 | }); 148 | return instance; 149 | } 150 | exports.deserialize = deserialize; 151 | /** 152 | * Serialize: Creates a ready-for-json-serialization object from the provided model instance. 153 | * Only @JsonProperty decorated properties in the model instance are processed. 154 | * 155 | * @param instance an instance of a model class 156 | * @returns {any} an object ready to be serialized to JSON 157 | */ 158 | function serialize(instance) { 159 | if (!utils_1.isTargetType(instance, 'object') || utils_1.isArrayOrArrayClass(instance)) { 160 | return instance; 161 | } 162 | var obj = {}; 163 | Object.keys(instance).forEach(function (key) { 164 | var metadata = getJsonProperty(instance, key); 165 | obj[metadata && metadata.name ? metadata.name : key] = serializeProperty(metadata, instance[key]); 166 | }); 167 | return obj; 168 | } 169 | exports.serialize = serialize; 170 | /** 171 | * Prepare a single property to be serialized to JSON. 172 | * 173 | * @param metadata 174 | * @param prop 175 | * @returns {any} 176 | */ 177 | function serializeProperty(metadata, prop) { 178 | if (!metadata || metadata.excludeToJson === true) { 179 | return; 180 | } 181 | if (metadata.customConverter) { 182 | return metadata.customConverter.toJson(prop); 183 | } 184 | if (!metadata.clazz) { 185 | return prop; 186 | } 187 | if (utils_1.isArrayOrArrayClass(prop)) { 188 | return prop.map(function (propItem) { return serialize(propItem); }); 189 | } 190 | return serialize(prop); 191 | } 192 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /typings/mocha/mocha.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for mocha 2.2.5 2 | // Project: http://mochajs.org/ 3 | // Definitions by: Kazi Manzur Rashid , otiai10 , jt000 , Vadim Macagon 4 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 5 | 6 | interface MochaSetupOptions { 7 | //milliseconds to wait before considering a test slow 8 | slow?: number; 9 | 10 | // timeout in milliseconds 11 | timeout?: number; 12 | 13 | // ui name "bdd", "tdd", "exports" etc 14 | ui?: string; 15 | 16 | //array of accepted globals 17 | globals?: any[]; 18 | 19 | // reporter instance (function or string), defaults to `mocha.reporters.Spec` 20 | reporter?: any; 21 | 22 | // bail on the first test failure 23 | bail?: boolean; 24 | 25 | // ignore global leaks 26 | ignoreLeaks?: boolean; 27 | 28 | // grep string or regexp to filter tests with 29 | grep?: any; 30 | } 31 | 32 | declare var mocha: Mocha; 33 | declare var describe: Mocha.IContextDefinition; 34 | declare var xdescribe: Mocha.IContextDefinition; 35 | // alias for `describe` 36 | declare var context: Mocha.IContextDefinition; 37 | // alias for `describe` 38 | declare var suite: Mocha.IContextDefinition; 39 | declare var it: Mocha.ITestDefinition; 40 | declare var xit: Mocha.ITestDefinition; 41 | // alias for `it` 42 | declare var test: Mocha.ITestDefinition; 43 | declare var specify: Mocha.ITestDefinition; 44 | 45 | interface MochaDone { 46 | (error?: any): any; 47 | } 48 | 49 | interface ActionFunction { 50 | (done: MochaDone): any | PromiseLike 51 | } 52 | 53 | declare function setup(action: ActionFunction): void; 54 | declare function teardown(action: ActionFunction): void; 55 | declare function suiteSetup(action: ActionFunction): void; 56 | declare function suiteTeardown(action: ActionFunction): void; 57 | declare function before(action: ActionFunction): void; 58 | declare function before(description: string, action: ActionFunction): void; 59 | declare function after(action: ActionFunction): void; 60 | declare function after(description: string, action: ActionFunction): void; 61 | declare function beforeEach(action: ActionFunction): void; 62 | declare function beforeEach(description: string, action: ActionFunction): void; 63 | declare function afterEach(action: ActionFunction): void; 64 | declare function afterEach(description: string, action: ActionFunction): void; 65 | 66 | declare class Mocha { 67 | currentTest: Mocha.ITestDefinition; 68 | constructor(options?: { 69 | grep?: RegExp; 70 | ui?: string; 71 | reporter?: string; 72 | timeout?: number; 73 | bail?: boolean; 74 | }); 75 | 76 | /** Setup mocha with the given options. */ 77 | setup(options: MochaSetupOptions): Mocha; 78 | bail(value?: boolean): Mocha; 79 | addFile(file: string): Mocha; 80 | /** Sets reporter by name, defaults to "spec". */ 81 | reporter(name: string): Mocha; 82 | /** Sets reporter constructor, defaults to mocha.reporters.Spec. */ 83 | reporter(reporter: (runner: Mocha.IRunner, options: any) => any): Mocha; 84 | ui(value: string): Mocha; 85 | grep(value: string): Mocha; 86 | grep(value: RegExp): Mocha; 87 | invert(): Mocha; 88 | ignoreLeaks(value: boolean): Mocha; 89 | checkLeaks(): Mocha; 90 | /** 91 | * Function to allow assertion libraries to throw errors directly into mocha. 92 | * This is useful when running tests in a browser because window.onerror will 93 | * only receive the 'message' attribute of the Error. 94 | */ 95 | throwError(error: Error): void; 96 | /** Enables growl support. */ 97 | growl(): Mocha; 98 | globals(value: string): Mocha; 99 | globals(values: string[]): Mocha; 100 | useColors(value: boolean): Mocha; 101 | useInlineDiffs(value: boolean): Mocha; 102 | timeout(value: number): Mocha; 103 | slow(value: number): Mocha; 104 | enableTimeouts(value: boolean): Mocha; 105 | asyncOnly(value: boolean): Mocha; 106 | noHighlighting(value: boolean): Mocha; 107 | /** Runs tests and invokes `onComplete()` when finished. */ 108 | run(onComplete?: (failures: number) => void): Mocha.IRunner; 109 | } 110 | 111 | // merge the Mocha class declaration with a module 112 | declare namespace Mocha { 113 | /** Partial interface for Mocha's `Runnable` class. */ 114 | interface IRunnable { 115 | title: string; 116 | fn: Function; 117 | async: boolean; 118 | sync: boolean; 119 | timedOut: boolean; 120 | } 121 | 122 | /** Partial interface for Mocha's `Suite` class. */ 123 | interface ISuite { 124 | parent: ISuite; 125 | title: string; 126 | 127 | fullTitle(): string; 128 | } 129 | 130 | /** Partial interface for Mocha's `Test` class. */ 131 | interface ITest extends IRunnable { 132 | parent: ISuite; 133 | pending: boolean; 134 | 135 | fullTitle(): string; 136 | } 137 | 138 | /** Partial interface for Mocha's `Runner` class. */ 139 | interface IRunner {} 140 | 141 | interface IContextDefinition { 142 | (description: string, spec: () => void): ISuite; 143 | only(description: string, spec: () => void): ISuite; 144 | skip(description: string, spec: () => void): void; 145 | timeout(ms: number): void; 146 | } 147 | 148 | interface ITestDefinition { 149 | (expectation: string, assertion?: ActionFunction): ITest; 150 | only(expectation: string, assertion?: ActionFunction): ITest; 151 | skip(expectation: string, assertion?: ActionFunction): void; 152 | timeout(ms: number): void; 153 | state: "failed" | "passed"; 154 | } 155 | 156 | export module reporters { 157 | export class Base { 158 | stats: { 159 | suites: number; 160 | tests: number; 161 | passes: number; 162 | pending: number; 163 | failures: number; 164 | }; 165 | 166 | constructor(runner: IRunner); 167 | } 168 | 169 | export class Doc extends Base {} 170 | export class Dot extends Base {} 171 | export class HTML extends Base {} 172 | export class HTMLCov extends Base {} 173 | export class JSON extends Base {} 174 | export class JSONCov extends Base {} 175 | export class JSONStream extends Base {} 176 | export class Landing extends Base {} 177 | export class List extends Base {} 178 | export class Markdown extends Base {} 179 | export class Min extends Base {} 180 | export class Nyan extends Base {} 181 | export class Progress extends Base { 182 | /** 183 | * @param options.open String used to indicate the start of the progress bar. 184 | * @param options.complete String used to indicate a complete test on the progress bar. 185 | * @param options.incomplete String used to indicate an incomplete test on the progress bar. 186 | * @param options.close String used to indicate the end of the progress bar. 187 | */ 188 | constructor(runner: IRunner, options?: { 189 | open?: string; 190 | complete?: string; 191 | incomplete?: string; 192 | close?: string; 193 | }); 194 | } 195 | export class Spec extends Base {} 196 | export class TAP extends Base {} 197 | export class XUnit extends Base { 198 | constructor(runner: IRunner, options?: any); 199 | } 200 | } 201 | } 202 | 203 | declare module "mocha" { 204 | export = Mocha; 205 | } 206 | -------------------------------------------------------------------------------- /index.ts: -------------------------------------------------------------------------------- 1 | import 'reflect-metadata'; 2 | import {isTargetType, isPrimitiveOrPrimitiveClass, isArrayOrArrayClass} from './libs/utils'; 3 | 4 | /** 5 | * provide interface to indicate the object is allowed to be traversed 6 | * 7 | * @interface 8 | */ 9 | export interface IGenericObject { 10 | [key: string]: any; 11 | } 12 | 13 | 14 | /** 15 | * Decorator variable name 16 | * 17 | * @const 18 | */ 19 | const JSON_META_DATA_KEY = 'JsonProperty'; 20 | 21 | /** 22 | * When custom mapping of a property is required. 23 | * 24 | * @interface 25 | */ 26 | export interface ICustomConverter { 27 | fromJson(data: any): any; 28 | toJson(data: any): any; 29 | } 30 | 31 | /** 32 | * IDecoratorMetaData 33 | * DecoratorConstraint 34 | * 35 | * @interface 36 | * @property {ICustomConverter} customConverter, will be used for mapping the property, if specified 37 | * @property {boolean} excludeToJson, will exclude the property for serialization, if true 38 | */ 39 | export interface IDecoratorMetaData { 40 | name?: string, 41 | clazz?: {new(): T}, 42 | customConverter?: ICustomConverter, 43 | excludeToJson?: boolean 44 | } 45 | 46 | /** 47 | * DecoratorMetaData 48 | * Model used for decoration parameters 49 | * 50 | * @class 51 | * @property {string} name, indicate which json property needed to map 52 | * @property {string} clazz, if the target is not primitive type, map it to corresponding class 53 | */ 54 | class DecoratorMetaData { 55 | constructor(public name?: string, public clazz?: {new(): T}) { 56 | } 57 | } 58 | 59 | /** 60 | * JsonProperty 61 | * 62 | * @function 63 | * @property {IDecoratorMetaData|string} metadata, encapsulate it to DecoratorMetaData for standard use 64 | * @return {(target:Object, targetKey:string | symbol)=> void} decorator function 65 | */ 66 | export function JsonProperty(metadata?: IDecoratorMetaData|string): (target: Object, targetKey: string | symbol)=> void { 67 | let decoratorMetaData: IDecoratorMetaData; 68 | 69 | if (isTargetType(metadata, 'string')) { 70 | decoratorMetaData = new DecoratorMetaData(metadata as string); 71 | } 72 | else if (isTargetType(metadata, 'object')) { 73 | decoratorMetaData = metadata as IDecoratorMetaData; 74 | } 75 | else { 76 | throw new Error('index.ts: meta data in Json property is undefined. meta data: ' + metadata) 77 | } 78 | 79 | return Reflect.metadata(JSON_META_DATA_KEY, decoratorMetaData); 80 | } 81 | 82 | 83 | /** 84 | * getClazz 85 | * 86 | * @function 87 | * @property {any} target object 88 | * @property {string} propertyKey, used as target property 89 | * @return {Function} Function/Class indicate the target property type 90 | * @description Used for type checking, if it is not primitive type, loop inside recursively 91 | */ 92 | function getClazz(target: T, propertyKey: string): {new(): T} { 93 | return Reflect.getMetadata('design:type', target, propertyKey) 94 | } 95 | 96 | 97 | /** 98 | * getJsonProperty 99 | * 100 | * @function 101 | * @property {any} target object 102 | * @property {string} propertyKey, used as target property 103 | * @return {IDecoratorMetaData} Obtain target property decorator meta data 104 | */ 105 | function getJsonProperty(target: any, propertyKey: string): IDecoratorMetaData { 106 | return Reflect.getMetadata(JSON_META_DATA_KEY, target, propertyKey); 107 | } 108 | 109 | /** 110 | * hasAnyNullOrUndefined 111 | * 112 | * @function 113 | * @property {...args:any[]} any arguments 114 | * @return {IDecoratorMetaData} check if any arguments is null or undefined 115 | */ 116 | function hasAnyNullOrUndefined(...args: any[]) { 117 | return args.some((arg: any) => arg === null || arg === undefined); 118 | } 119 | 120 | 121 | function mapFromJson(decoratorMetadata: IDecoratorMetaData, instance: T, json: IGenericObject, key: any): any { 122 | /** 123 | * if decorator name is not found, use target property key as decorator name. It means mapping it directly 124 | */ 125 | let decoratorName = decoratorMetadata.name || key; 126 | let innerJson: any = json ? json[decoratorName] : undefined; 127 | let clazz = getClazz(instance, key); 128 | if (isArrayOrArrayClass(clazz)) { 129 | let metadata = getJsonProperty(instance, key); 130 | if (metadata && metadata.clazz || isPrimitiveOrPrimitiveClass(clazz)) { 131 | if (innerJson && isArrayOrArrayClass(innerJson)) { 132 | return innerJson.map( 133 | (item: any) => deserialize(metadata.clazz, item) 134 | ); 135 | } 136 | return; 137 | } else { 138 | return innerJson; 139 | } 140 | } 141 | 142 | if (!isPrimitiveOrPrimitiveClass(clazz)) { 143 | return deserialize(clazz, innerJson); 144 | } 145 | 146 | return json ? json[decoratorName] : undefined; 147 | } 148 | 149 | /** 150 | * deserialize 151 | * 152 | * @function 153 | * @param {{new():T}} clazz, class type which is going to initialize and hold a mapping json 154 | * @param {Object} json, input json object which to be mapped 155 | * 156 | * @return {T} return mapped object 157 | */ 158 | export function deserialize(Clazz: {new(): T}, json: IGenericObject): T { 159 | /** 160 | * As it is a recursive function, ignore any arguments that are unset 161 | */ 162 | if (hasAnyNullOrUndefined(Clazz, json)) { 163 | return void 0; 164 | } 165 | 166 | /** 167 | * Prevent non-json continue 168 | */ 169 | if (!isTargetType(json, 'object')) { 170 | return void 0; 171 | } 172 | /** 173 | * init root class to contain json 174 | */ 175 | let instance: IGenericObject = new Clazz(); 176 | 177 | Object.keys(instance).forEach((key: string) => { 178 | /** 179 | * get decoratorMetaData, structure: { name?:string, clazz?:{ new():T } } 180 | */ 181 | let decoratorMetaData = getJsonProperty(instance, key); 182 | 183 | /** 184 | * pass value to instance 185 | */ 186 | if (decoratorMetaData && decoratorMetaData.customConverter) { 187 | instance[key] = decoratorMetaData.customConverter.fromJson(json[decoratorMetaData.name || key]); 188 | } else { 189 | instance[key] = decoratorMetaData ? mapFromJson(decoratorMetaData, instance, json, key) : json[key]; 190 | } 191 | 192 | }); 193 | 194 | return instance as T; 195 | } 196 | 197 | /** 198 | * Serialize: Creates a ready-for-json-serialization object from the provided model instance. 199 | * Only @JsonProperty decorated properties in the model instance are processed. 200 | * 201 | * @param instance an instance of a model class 202 | * @returns {any} an object ready to be serialized to JSON 203 | */ 204 | export function serialize(instance: any): any { 205 | 206 | if (!isTargetType(instance, 'object') || isArrayOrArrayClass(instance)) { 207 | return instance; 208 | } 209 | 210 | const obj: any = {}; 211 | Object.keys(instance).forEach(key => { 212 | const metadata = getJsonProperty(instance, key); 213 | obj[metadata && metadata.name ? metadata.name : key] = serializeProperty(metadata, instance[key]); 214 | }); 215 | return obj; 216 | } 217 | 218 | /** 219 | * Prepare a single property to be serialized to JSON. 220 | * 221 | * @param metadata 222 | * @param prop 223 | * @returns {any} 224 | */ 225 | function serializeProperty(metadata: IDecoratorMetaData, prop: any): any { 226 | 227 | if (!metadata || metadata.excludeToJson === true) { 228 | return; 229 | } 230 | 231 | if (metadata.customConverter) { 232 | return metadata.customConverter.toJson(prop); 233 | } 234 | 235 | if (!metadata.clazz) { 236 | return prop; 237 | } 238 | 239 | if (isArrayOrArrayClass(prop)) { 240 | return prop.map((propItem: any) => serialize(propItem)); 241 | } 242 | 243 | return serialize(prop); 244 | } 245 | -------------------------------------------------------------------------------- /spec/index.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | 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; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | var chai_1 = require('chai'); 12 | var index_1 = require('../index'); 13 | var dateconverter_1 = require('./common/dateconverter'); 14 | var Student = (function () { 15 | function Student() { 16 | this.dateOfBirth = undefined; 17 | this.fullName = void 0; 18 | } 19 | __decorate([ 20 | index_1.JsonProperty('name'), 21 | __metadata('design:type', String) 22 | ], Student.prototype, "fullName", void 0); 23 | __decorate([ 24 | index_1.JsonProperty({ name: 'dob', customConverter: dateconverter_1.default }), 25 | __metadata('design:type', Date) 26 | ], Student.prototype, "dateOfBirth", void 0); 27 | return Student; 28 | }()); 29 | var Address = (function () { 30 | function Address() { 31 | this.firstLine = void 0; 32 | this.secondLine = void 0; 33 | this.city = void 0; 34 | this.student = void 0; 35 | } 36 | __decorate([ 37 | index_1.JsonProperty('first-line'), 38 | __metadata('design:type', String) 39 | ], Address.prototype, "firstLine", void 0); 40 | __decorate([ 41 | index_1.JsonProperty('second-line'), 42 | __metadata('design:type', String) 43 | ], Address.prototype, "secondLine", void 0); 44 | __decorate([ 45 | index_1.JsonProperty({ clazz: Student }), 46 | __metadata('design:type', Student) 47 | ], Address.prototype, "student", void 0); 48 | return Address; 49 | }()); 50 | var Person = (function () { 51 | function Person() { 52 | this.name = void 0; 53 | this.surname = void 0; 54 | this.age = void 0; 55 | this.addressArr = void 0; 56 | this.address = void 0; 57 | } 58 | __decorate([ 59 | index_1.JsonProperty('Name'), 60 | __metadata('design:type', String) 61 | ], Person.prototype, "name", void 0); 62 | __decorate([ 63 | index_1.JsonProperty('xing'), 64 | __metadata('design:type', String) 65 | ], Person.prototype, "surname", void 0); 66 | __decorate([ 67 | index_1.JsonProperty({ clazz: Address, name: 'AddressArr' }), 68 | __metadata('design:type', Array) 69 | ], Person.prototype, "addressArr", void 0); 70 | __decorate([ 71 | index_1.JsonProperty({ clazz: Address, name: 'Address' }), 72 | __metadata('design:type', Address) 73 | ], Person.prototype, "address", void 0); 74 | return Person; 75 | }()); 76 | describe('index()', function () { 77 | it('simple json object #1', function () { 78 | var json = { 79 | "Name": "Mark", 80 | "xing": "Galea", 81 | "age": 30, 82 | "AddressArr": [], 83 | "Address": null 84 | }; 85 | var person = index_1.deserialize(Person, json); 86 | chai_1.expect(person.address).to.be.equals(void 0); 87 | chai_1.expect(person.name).to.be.equal("Mark"); 88 | chai_1.expect(person.surname).to.be.equal("Galea"); 89 | chai_1.expect(person.addressArr).to.be.empty; 90 | }); 91 | it('simple json object #2', function () { 92 | var addressjson = { 93 | "first-line": "Some where", 94 | "second-line": "Over Here", 95 | "city": "In This City", 96 | "student": { 97 | name: "Ailun" 98 | } 99 | }; 100 | var address = index_1.deserialize(Address, addressjson); 101 | chai_1.expect(address.firstLine).to.be.equal("Some where"); 102 | chai_1.expect(address.secondLine).to.be.equal("Over Here"); 103 | chai_1.expect(address.city).to.be.equal("In This City"); 104 | chai_1.expect(address.student).to.be.an('object'); 105 | chai_1.expect(address.student.fullName).to.be.equal('Ailun'); 106 | }); 107 | it('complex json object #1', function () { 108 | var json = { 109 | "Name": "Mark", 110 | "xing": "Galea", 111 | "age": 30, 112 | "AddressArr": [ 113 | { 114 | "first-line": "Some where", 115 | "second-line": "Over Here", 116 | "city": "In This City", 117 | "student": { 118 | name1: "Ailun" 119 | } 120 | }, 121 | { 122 | "first-line": "Some where", 123 | "second-line": "Over Here", 124 | "city": "In This City", 125 | "student": { 126 | name1: "Ailun" 127 | } 128 | } 129 | ], 130 | "Address": { 131 | "first-line": "Some where", 132 | "second-line": "Over Here", 133 | "city": "In This City", 134 | "student": { 135 | name: "Ailun" 136 | } 137 | } 138 | }; 139 | var person = index_1.deserialize(Person, json); 140 | chai_1.expect(person.address).to.be.an.instanceOf(Address); 141 | chai_1.expect(person.age).to.be.a('number'); 142 | chai_1.expect(person.name).to.be.a('string'); 143 | chai_1.expect(person.address).to.be.an('object'); 144 | chai_1.expect(person.addressArr.length).to.be.equals(2); 145 | chai_1.expect(person.address.student.fullName).to.be.equals('Ailun'); 146 | }); 147 | it('empty json object #1', function () { 148 | var json = {}; 149 | var person = index_1.deserialize(Person, json); 150 | chai_1.expect(person.address).to.be.equal(void 0); 151 | chai_1.expect(person.name).to.be.equal(void 0); 152 | chai_1.expect(person.surname).to.be.equal(void 0); 153 | chai_1.expect(person.addressArr).to.be.equal(void 0); 154 | }); 155 | it('empty json object #2', function () { 156 | var json = null; 157 | var person = index_1.deserialize(Person, json); 158 | chai_1.expect(person).to.be.equals(void 0); 159 | }); 160 | it('empty json object #3', function () { 161 | var json = void 0; 162 | var person = index_1.deserialize(Person, json); 163 | chai_1.expect(person).to.be.equals(void 0); 164 | }); 165 | it('invalid primitive value #1', function () { 166 | var json = 123; 167 | var person = index_1.deserialize(Person, json); 168 | chai_1.expect(person).to.be.equals(void 0); 169 | }); 170 | it('invalid primitive value #2', function () { 171 | var json = ''; 172 | var person = index_1.deserialize(Person, json); 173 | chai_1.expect(person).to.be.equals(void 0); 174 | }); 175 | it('invalid primitive value #3', function () { 176 | var json = NaN; 177 | var person = index_1.deserialize(Person, json); 178 | chai_1.expect(person).to.be.equals(void 0); 179 | }); 180 | it('invalid json object #1', function () { 181 | var json = { 182 | "NameTest": "Mark", 183 | }; 184 | var person = index_1.deserialize(Person, json); 185 | chai_1.expect(person.name).to.be.equals(void 0); 186 | }); 187 | it('should use a custom converter if available', function () { 188 | var json = { 189 | "name": "John Doe", 190 | dob: "1995-11-10" 191 | }; 192 | var student = index_1.deserialize(Student, json); 193 | chai_1.expect(student.fullName).to.be.equals('John Doe'); 194 | chai_1.expect(student.dateOfBirth).to.be.instanceof(Date); 195 | chai_1.expect(student.dateOfBirth.toString()).to.equal(new Date("1995-11-10").toString()); 196 | }); 197 | }); 198 | //# sourceMappingURL=index.js.map -------------------------------------------------------------------------------- /spec/serialize.js: -------------------------------------------------------------------------------- 1 | "use strict"; 2 | var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) { 3 | var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; 4 | if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); 5 | 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; 6 | return c > 3 && r && Object.defineProperty(target, key, r), r; 7 | }; 8 | var __metadata = (this && this.__metadata) || function (k, v) { 9 | if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v); 10 | }; 11 | var chai_1 = require('chai'); 12 | var index_1 = require('../index'); 13 | var dateconverter_1 = require('./common/dateconverter'); 14 | describe('serialize', function () { 15 | it('should use the property name given in the meta data', function () { 16 | var ClassWithPrimitiveProp = (function () { 17 | function ClassWithPrimitiveProp() { 18 | this.name = undefined; 19 | } 20 | __decorate([ 21 | index_1.JsonProperty('theName'), 22 | __metadata('design:type', String) 23 | ], ClassWithPrimitiveProp.prototype, "name", void 0); 24 | return ClassWithPrimitiveProp; 25 | }()); 26 | var instance = new ClassWithPrimitiveProp(); 27 | instance.name = 'Jim'; 28 | var serializedInstance = index_1.serialize(instance); 29 | chai_1.expect(serializedInstance.theName).to.equal('Jim'); 30 | }); 31 | describe('primitive types', function () { 32 | var primitiveTypes = ['some-string', true, 25, new Number(25), new Boolean(true)]; 33 | primitiveTypes.forEach(function (primitiveType) { 34 | it("should keep " + typeof primitiveType + " as is", function () { 35 | var PrimitiveProp = (function () { 36 | function PrimitiveProp() { 37 | this.someProp = primitiveType; 38 | } 39 | __decorate([ 40 | index_1.JsonProperty('someProp'), 41 | __metadata('design:type', Object) 42 | ], PrimitiveProp.prototype, "someProp", void 0); 43 | return PrimitiveProp; 44 | }()); 45 | var instance = new PrimitiveProp(); 46 | // instance.someProp = primitiveType; 47 | var serializedInstance = index_1.serialize(instance); 48 | chai_1.expect(serializedInstance.someProp).to.equal(primitiveType); 49 | }); 50 | }); 51 | }); 52 | it('should keep unspecified objects as is', function () { 53 | var ClassWithUnspecObject = (function () { 54 | function ClassWithUnspecObject() { 55 | this.date = new Date(); 56 | } 57 | __decorate([ 58 | index_1.JsonProperty('date'), 59 | __metadata('design:type', Date) 60 | ], ClassWithUnspecObject.prototype, "date", void 0); 61 | return ClassWithUnspecObject; 62 | }()); 63 | var instance = new ClassWithUnspecObject(); 64 | var serializedInstance = index_1.serialize(instance); 65 | chai_1.expect(serializedInstance.date).to.equal(instance.date); 66 | }); 67 | it('should use custom converter if available', function () { 68 | var ClassWithCustomConv = (function () { 69 | function ClassWithCustomConv() { 70 | this.date = new Date(); 71 | } 72 | __decorate([ 73 | index_1.JsonProperty({ name: 'date', customConverter: dateconverter_1.default }), 74 | __metadata('design:type', Date) 75 | ], ClassWithCustomConv.prototype, "date", void 0); 76 | return ClassWithCustomConv; 77 | }()); 78 | var instance = new ClassWithCustomConv(); 79 | var serializedInstance = index_1.serialize(instance); 80 | chai_1.expect(serializedInstance.date).to.equal('some-date'); 81 | }); 82 | it('should exclude properties if specified', function () { 83 | var ClassWithExcludedProp = (function () { 84 | function ClassWithExcludedProp() { 85 | this.name = 'John'; 86 | this.lastName = 'Doe'; 87 | } 88 | __decorate([ 89 | index_1.JsonProperty('name'), 90 | __metadata('design:type', String) 91 | ], ClassWithExcludedProp.prototype, "name", void 0); 92 | __decorate([ 93 | index_1.JsonProperty({ name: 'lastName', excludeToJson: true }), 94 | __metadata('design:type', String) 95 | ], ClassWithExcludedProp.prototype, "lastName", void 0); 96 | return ClassWithExcludedProp; 97 | }()); 98 | var instance = new ClassWithExcludedProp(); 99 | var serializedInstance = index_1.serialize(instance); 100 | chai_1.expect(serializedInstance.name).to.equal('John'); 101 | chai_1.expect(serializedInstance.lastName).to.be.undefined; 102 | }); 103 | it('should work recursively if clazz is specified in meta data', function () { 104 | var OtherClass = (function () { 105 | function OtherClass() { 106 | this.date = new Date(); 107 | } 108 | __decorate([ 109 | index_1.JsonProperty({ name: 'date', customConverter: dateconverter_1.default }), 110 | __metadata('design:type', Date) 111 | ], OtherClass.prototype, "date", void 0); 112 | return OtherClass; 113 | }()); 114 | var ClassWithClassProp = (function () { 115 | function ClassWithClassProp() { 116 | this.other = new OtherClass(); 117 | } 118 | __decorate([ 119 | index_1.JsonProperty({ name: 'other', clazz: OtherClass }), 120 | __metadata('design:type', OtherClass) 121 | ], ClassWithClassProp.prototype, "other", void 0); 122 | return ClassWithClassProp; 123 | }()); 124 | var instance = new ClassWithClassProp(); 125 | var serializedInstance = index_1.serialize(instance); 126 | chai_1.expect(serializedInstance.other.date).to.equal('some-date'); 127 | }); 128 | describe('Arrays', function () { 129 | it('should keep as is if no clazz is specified', function () { 130 | var ClassWithArrayProp = (function () { 131 | function ClassWithArrayProp() { 132 | this.items = [new Date(), new Date()]; 133 | } 134 | __decorate([ 135 | index_1.JsonProperty('items'), 136 | __metadata('design:type', Array) 137 | ], ClassWithArrayProp.prototype, "items", void 0); 138 | return ClassWithArrayProp; 139 | }()); 140 | var instance = new ClassWithArrayProp(); 141 | var serializedInstance = index_1.serialize(instance); 142 | chai_1.expect(serializedInstance.items).to.be.instanceof(Array); 143 | chai_1.expect(serializedInstance.items.length).to.equal(2); 144 | chai_1.expect(serializedInstance.items[0]).to.equal(instance.items[0]); 145 | chai_1.expect(serializedInstance.items[1]).to.equal(instance.items[1]); 146 | }); 147 | it('should apply serialize for all array items if clazz is specified', function () { 148 | var OtherClass = (function () { 149 | function OtherClass() { 150 | this.date = new Date(); 151 | } 152 | __decorate([ 153 | index_1.JsonProperty({ name: 'date', customConverter: dateconverter_1.default }), 154 | __metadata('design:type', Date) 155 | ], OtherClass.prototype, "date", void 0); 156 | return OtherClass; 157 | }()); 158 | var ClassWithArrayProp = (function () { 159 | function ClassWithArrayProp() { 160 | this.items = [new OtherClass(), new OtherClass()]; 161 | } 162 | __decorate([ 163 | index_1.JsonProperty({ name: 'items', clazz: OtherClass }), 164 | __metadata('design:type', Array) 165 | ], ClassWithArrayProp.prototype, "items", void 0); 166 | return ClassWithArrayProp; 167 | }()); 168 | var instance = new ClassWithArrayProp(); 169 | var serializedInstance = index_1.serialize(instance); 170 | chai_1.expect(serializedInstance.items).to.be.instanceof(Array); 171 | chai_1.expect(serializedInstance.items.length).to.equal(2); 172 | chai_1.expect(serializedInstance.items[0].date).to.equal('some-date'); 173 | chai_1.expect(serializedInstance.items[1].date).to.equal('some-date'); 174 | }); 175 | }); 176 | }); 177 | //# sourceMappingURL=serialize.js.map -------------------------------------------------------------------------------- /typings/chai/chai.d.ts: -------------------------------------------------------------------------------- 1 | // Type definitions for chai 3.4.0 2 | // Project: http://chaijs.com/ 3 | // Definitions by: Jed Mao , 4 | // Bart van der Schoor , 5 | // Andrew Brown , 6 | // Olivier Chevet , 7 | // Matt Wistrand 8 | // Definitions: https://github.com/DefinitelyTyped/DefinitelyTyped 9 | 10 | // 11 | 12 | declare namespace Chai { 13 | 14 | interface ChaiStatic { 15 | expect: ExpectStatic; 16 | should(): Should; 17 | /** 18 | * Provides a way to extend the internals of Chai 19 | */ 20 | use(fn: (chai: any, utils: any) => void): ChaiStatic; 21 | assert: AssertStatic; 22 | config: Config; 23 | AssertionError: typeof AssertionError; 24 | } 25 | 26 | export interface ExpectStatic extends AssertionStatic { 27 | fail(actual?: any, expected?: any, message?: string, operator?: string): void; 28 | } 29 | 30 | export interface AssertStatic extends Assert { 31 | } 32 | 33 | export interface AssertionStatic { 34 | (target: any, message?: string): Assertion; 35 | } 36 | 37 | interface ShouldAssertion { 38 | equal(value1: any, value2: any, message?: string): void; 39 | Throw: ShouldThrow; 40 | throw: ShouldThrow; 41 | exist(value: any, message?: string): void; 42 | } 43 | 44 | interface Should extends ShouldAssertion { 45 | not: ShouldAssertion; 46 | fail(actual: any, expected: any, message?: string, operator?: string): void; 47 | } 48 | 49 | interface ShouldThrow { 50 | (actual: Function): void; 51 | (actual: Function, expected: string|RegExp, message?: string): void; 52 | (actual: Function, constructor: Error|Function, expected?: string|RegExp, message?: string): void; 53 | } 54 | 55 | interface Assertion extends LanguageChains, NumericComparison, TypeComparison { 56 | not: Assertion; 57 | deep: Deep; 58 | any: KeyFilter; 59 | all: KeyFilter; 60 | a: TypeComparison; 61 | an: TypeComparison; 62 | include: Include; 63 | includes: Include; 64 | contain: Include; 65 | contains: Include; 66 | ok: Assertion; 67 | true: Assertion; 68 | false: Assertion; 69 | null: Assertion; 70 | undefined: Assertion; 71 | NaN: Assertion; 72 | exist: Assertion; 73 | empty: Assertion; 74 | arguments: Assertion; 75 | Arguments: Assertion; 76 | equal: Equal; 77 | equals: Equal; 78 | eq: Equal; 79 | eql: Equal; 80 | eqls: Equal; 81 | property: Property; 82 | ownProperty: OwnProperty; 83 | haveOwnProperty: OwnProperty; 84 | ownPropertyDescriptor: OwnPropertyDescriptor; 85 | haveOwnPropertyDescriptor: OwnPropertyDescriptor; 86 | length: Length; 87 | lengthOf: Length; 88 | match: Match; 89 | matches: Match; 90 | string(string: string, message?: string): Assertion; 91 | keys: Keys; 92 | key(string: string): Assertion; 93 | throw: Throw; 94 | throws: Throw; 95 | Throw: Throw; 96 | respondTo: RespondTo; 97 | respondsTo: RespondTo; 98 | itself: Assertion; 99 | satisfy: Satisfy; 100 | satisfies: Satisfy; 101 | closeTo: CloseTo; 102 | approximately: CloseTo; 103 | members: Members; 104 | increase: PropertyChange; 105 | increases: PropertyChange; 106 | decrease: PropertyChange; 107 | decreases: PropertyChange; 108 | change: PropertyChange; 109 | changes: PropertyChange; 110 | extensible: Assertion; 111 | sealed: Assertion; 112 | frozen: Assertion; 113 | oneOf(list: any[], message?: string): Assertion; 114 | } 115 | 116 | interface LanguageChains { 117 | to: Assertion; 118 | be: Assertion; 119 | been: Assertion; 120 | is: Assertion; 121 | that: Assertion; 122 | which: Assertion; 123 | and: Assertion; 124 | has: Assertion; 125 | have: Assertion; 126 | with: Assertion; 127 | at: Assertion; 128 | of: Assertion; 129 | same: Assertion; 130 | } 131 | 132 | interface NumericComparison { 133 | above: NumberComparer; 134 | gt: NumberComparer; 135 | greaterThan: NumberComparer; 136 | least: NumberComparer; 137 | gte: NumberComparer; 138 | below: NumberComparer; 139 | lt: NumberComparer; 140 | lessThan: NumberComparer; 141 | most: NumberComparer; 142 | lte: NumberComparer; 143 | within(start: number, finish: number, message?: string): Assertion; 144 | } 145 | 146 | interface NumberComparer { 147 | (value: number, message?: string): Assertion; 148 | } 149 | 150 | interface TypeComparison { 151 | (type: string, message?: string): Assertion; 152 | instanceof: InstanceOf; 153 | instanceOf: InstanceOf; 154 | } 155 | 156 | interface InstanceOf { 157 | (constructor: Object, message?: string): Assertion; 158 | } 159 | 160 | interface CloseTo { 161 | (expected: number, delta: number, message?: string): Assertion; 162 | } 163 | 164 | interface Deep { 165 | equal: Equal; 166 | include: Include; 167 | property: Property; 168 | members: Members; 169 | } 170 | 171 | interface KeyFilter { 172 | keys: Keys; 173 | } 174 | 175 | interface Equal { 176 | (value: any, message?: string): Assertion; 177 | } 178 | 179 | interface Property { 180 | (name: string, value?: any, message?: string): Assertion; 181 | } 182 | 183 | interface OwnProperty { 184 | (name: string, message?: string): Assertion; 185 | } 186 | 187 | interface OwnPropertyDescriptor { 188 | (name: string, descriptor: PropertyDescriptor, message?: string): Assertion; 189 | (name: string, message?: string): Assertion; 190 | } 191 | 192 | interface Length extends LanguageChains, NumericComparison { 193 | (length: number, message?: string): Assertion; 194 | } 195 | 196 | interface Include { 197 | (value: Object, message?: string): Assertion; 198 | (value: string, message?: string): Assertion; 199 | (value: number, message?: string): Assertion; 200 | keys: Keys; 201 | members: Members; 202 | any: KeyFilter; 203 | all: KeyFilter; 204 | } 205 | 206 | interface Match { 207 | (regexp: RegExp|string, message?: string): Assertion; 208 | } 209 | 210 | interface Keys { 211 | (...keys: string[]): Assertion; 212 | (keys: any[]): Assertion; 213 | (keys: Object): Assertion; 214 | } 215 | 216 | interface Throw { 217 | (): Assertion; 218 | (expected: string, message?: string): Assertion; 219 | (expected: RegExp, message?: string): Assertion; 220 | (constructor: Error, expected?: string, message?: string): Assertion; 221 | (constructor: Error, expected?: RegExp, message?: string): Assertion; 222 | (constructor: Function, expected?: string, message?: string): Assertion; 223 | (constructor: Function, expected?: RegExp, message?: string): Assertion; 224 | } 225 | 226 | interface RespondTo { 227 | (method: string, message?: string): Assertion; 228 | } 229 | 230 | interface Satisfy { 231 | (matcher: Function, message?: string): Assertion; 232 | } 233 | 234 | interface Members { 235 | (set: any[], message?: string): Assertion; 236 | } 237 | 238 | interface PropertyChange { 239 | (object: Object, prop: string, msg?: string): Assertion; 240 | } 241 | 242 | export interface Assert { 243 | /** 244 | * @param expression Expression to test for truthiness. 245 | * @param message Message to display on error. 246 | */ 247 | (expression: any, message?: string): void; 248 | 249 | fail(actual?: any, expected?: any, msg?: string, operator?: string): void; 250 | 251 | ok(val: any, msg?: string): void; 252 | isOk(val: any, msg?: string): void; 253 | notOk(val: any, msg?: string): void; 254 | isNotOk(val: any, msg?: string): void; 255 | 256 | equal(act: any, exp: any, msg?: string): void; 257 | notEqual(act: any, exp: any, msg?: string): void; 258 | 259 | strictEqual(act: any, exp: any, msg?: string): void; 260 | notStrictEqual(act: any, exp: any, msg?: string): void; 261 | 262 | deepEqual(act: any, exp: any, msg?: string): void; 263 | notDeepEqual(act: any, exp: any, msg?: string): void; 264 | 265 | isTrue(val: any, msg?: string): void; 266 | isFalse(val: any, msg?: string): void; 267 | 268 | isNotTrue(val: any, msg?: string): void; 269 | isNotFalse(val: any, msg?: string): void; 270 | 271 | isNull(val: any, msg?: string): void; 272 | isNotNull(val: any, msg?: string): void; 273 | 274 | isUndefined(val: any, msg?: string): void; 275 | isDefined(val: any, msg?: string): void; 276 | 277 | isNaN(val: any, msg?: string): void; 278 | isNotNaN(val: any, msg?: string): void; 279 | 280 | isAbove(val: number, abv: number, msg?: string): void; 281 | isBelow(val: number, blw: number, msg?: string): void; 282 | 283 | isAtLeast(val: number, atlst: number, msg?: string): void; 284 | isAtMost(val: number, atmst: number, msg?: string): void; 285 | 286 | isFunction(val: any, msg?: string): void; 287 | isNotFunction(val: any, msg?: string): void; 288 | 289 | isObject(val: any, msg?: string): void; 290 | isNotObject(val: any, msg?: string): void; 291 | 292 | isArray(val: any, msg?: string): void; 293 | isNotArray(val: any, msg?: string): void; 294 | 295 | isString(val: any, msg?: string): void; 296 | isNotString(val: any, msg?: string): void; 297 | 298 | isNumber(val: any, msg?: string): void; 299 | isNotNumber(val: any, msg?: string): void; 300 | 301 | isBoolean(val: any, msg?: string): void; 302 | isNotBoolean(val: any, msg?: string): void; 303 | 304 | typeOf(val: any, type: string, msg?: string): void; 305 | notTypeOf(val: any, type: string, msg?: string): void; 306 | 307 | instanceOf(val: any, type: Function, msg?: string): void; 308 | notInstanceOf(val: any, type: Function, msg?: string): void; 309 | 310 | include(exp: string, inc: any, msg?: string): void; 311 | include(exp: any[], inc: any, msg?: string): void; 312 | 313 | notInclude(exp: string, inc: any, msg?: string): void; 314 | notInclude(exp: any[], inc: any, msg?: string): void; 315 | 316 | match(exp: any, re: RegExp, msg?: string): void; 317 | notMatch(exp: any, re: RegExp, msg?: string): void; 318 | 319 | property(obj: Object, prop: string, msg?: string): void; 320 | notProperty(obj: Object, prop: string, msg?: string): void; 321 | deepProperty(obj: Object, prop: string, msg?: string): void; 322 | notDeepProperty(obj: Object, prop: string, msg?: string): void; 323 | 324 | propertyVal(obj: Object, prop: string, val: any, msg?: string): void; 325 | propertyNotVal(obj: Object, prop: string, val: any, msg?: string): void; 326 | 327 | deepPropertyVal(obj: Object, prop: string, val: any, msg?: string): void; 328 | deepPropertyNotVal(obj: Object, prop: string, val: any, msg?: string): void; 329 | 330 | lengthOf(exp: any, len: number, msg?: string): void; 331 | //alias frenzy 332 | throw(fn: Function, msg?: string): void; 333 | throw(fn: Function, regExp: RegExp): void; 334 | throw(fn: Function, errType: Function, msg?: string): void; 335 | throw(fn: Function, errType: Function, regExp: RegExp): void; 336 | 337 | throws(fn: Function, msg?: string): void; 338 | throws(fn: Function, regExp: RegExp): void; 339 | throws(fn: Function, errType: Function, msg?: string): void; 340 | throws(fn: Function, errType: Function, regExp: RegExp): void; 341 | 342 | Throw(fn: Function, msg?: string): void; 343 | Throw(fn: Function, regExp: RegExp): void; 344 | Throw(fn: Function, errType: Function, msg?: string): void; 345 | Throw(fn: Function, errType: Function, regExp: RegExp): void; 346 | 347 | doesNotThrow(fn: Function, msg?: string): void; 348 | doesNotThrow(fn: Function, regExp: RegExp): void; 349 | doesNotThrow(fn: Function, errType: Function, msg?: string): void; 350 | doesNotThrow(fn: Function, errType: Function, regExp: RegExp): void; 351 | 352 | operator(val: any, operator: string, val2: any, msg?: string): void; 353 | closeTo(act: number, exp: number, delta: number, msg?: string): void; 354 | approximately(act: number, exp: number, delta: number, msg?: string): void; 355 | 356 | sameMembers(set1: any[], set2: any[], msg?: string): void; 357 | sameDeepMembers(set1: any[], set2: any[], msg?: string): void; 358 | includeMembers(superset: any[], subset: any[], msg?: string): void; 359 | 360 | ifError(val: any, msg?: string): void; 361 | 362 | isExtensible(obj: {}, msg?: string): void; 363 | extensible(obj: {}, msg?: string): void; 364 | isNotExtensible(obj: {}, msg?: string): void; 365 | notExtensible(obj: {}, msg?: string): void; 366 | 367 | isSealed(obj: {}, msg?: string): void; 368 | sealed(obj: {}, msg?: string): void; 369 | isNotSealed(obj: {}, msg?: string): void; 370 | notSealed(obj: {}, msg?: string): void; 371 | 372 | isFrozen(obj: Object, msg?: string): void; 373 | frozen(obj: Object, msg?: string): void; 374 | isNotFrozen(obj: Object, msg?: string): void; 375 | notFrozen(obj: Object, msg?: string): void; 376 | 377 | oneOf(inList: any, list: any[], msg?: string): void; 378 | } 379 | 380 | export interface Config { 381 | /** 382 | * Default: false 383 | */ 384 | includeStack: boolean; 385 | 386 | /** 387 | * Default: true 388 | */ 389 | showDiff: boolean; 390 | 391 | /** 392 | * Default: 40 393 | */ 394 | truncateThreshold: number; 395 | } 396 | 397 | export class AssertionError { 398 | constructor(message: string, _props?: any, ssf?: Function); 399 | name: string; 400 | message: string; 401 | showDiff: boolean; 402 | stack: string; 403 | } 404 | } 405 | 406 | declare var chai: Chai.ChaiStatic; 407 | 408 | declare module "chai" { 409 | export = chai; 410 | } 411 | 412 | interface Object { 413 | should: Chai.Assertion; 414 | } 415 | -------------------------------------------------------------------------------- /bower_components/chai/ReleaseNotes.md: -------------------------------------------------------------------------------- 1 | # Release Notes 2 | 3 | ## 1.8.1 / 2013-10-10 4 | 5 | The following changes are required if you are upgrading from the previous version: 6 | 7 | - **Users:** 8 | - Refresh `node_modules` folder for updated dependencies. 9 | - **Plugin Developers:** 10 | - No changes required 11 | - **Core Contributors:** 12 | - Refresh `node_modules` folder for updated dependencies. 13 | 14 | ### Browserify 15 | 16 | This is a small patch that updates the dependency tree so browserify users can install 17 | chai. (Remove conditional requires) 18 | 19 | ## 1.8.0 / 2013-09-18 20 | 21 | The following changes are required if you are upgrading from the previous version: 22 | 23 | - **Users:** 24 | - See `deep.equal` notes. 25 | - **Plugin Developers:** 26 | - No changes required 27 | - **Core Contributors:** 28 | - Refresh `node_modules` folder for updated dependencies. 29 | 30 | ### Deep Equals 31 | 32 | This version of Chai focused on a overhaul to the deep equal utility. The code for this 33 | tool has been removed from the core lib and can now be found at: 34 | [chai / deep-eql](https://github.com/chaijs/deep-eql). As stated in previous releases, 35 | this is part of a larger initiative to provide transparency, independent testing, and coverage for 36 | some of the more complicated internal tools. 37 | 38 | For the most part `.deep.equal` will behave the same as it has. However, in order to provide a 39 | consistent ruleset across all types being tested, the following changes have been made and _might_ 40 | require changes to your tests. 41 | 42 | **1.** Strict equality for non-traversable nodes according to [egal](http://wiki.ecmascript.org/doku.php?id=harmony:egal). 43 | 44 | _Previously:_ Non-traversable equal via `===`. 45 | 46 | ```js 47 | expect(NaN).to.deep.equal(NaN); 48 | expect(-0).to.not.deep.equal(+0); 49 | ``` 50 | 51 | **2.** Arguments are not Arrays (and all types must be equal): 52 | 53 | _Previously:_ Some crazy nonsense that led to empty arrays deep equaling empty objects deep equaling dates. 54 | 55 | ```js 56 | expect(arguments).to.not.deep.equal([]); 57 | expect(Array.prototype.slice.call(arguments)).to.deep.equal([]); 58 | ``` 59 | 60 | - [#156](https://github.com/chaijs/chai/issues/156) Empty object is eql to empty array 61 | - [#192](https://github.com/chaijs/chai/issues/192) empty object is eql to a Date object 62 | - [#194](https://github.com/chaijs/chai/issues/194) refactor deep-equal utility 63 | 64 | ### CI and Browser Testing 65 | 66 | Chai now runs the browser CI suite using [Karma](http://karma-runner.github.io/) directed at 67 | [SauceLabs](https://saucelabs.com/). This means we get to know where our browser support stands... 68 | and we get a cool badge: 69 | 70 | [![Selenium Test Status](https://saucelabs.com/browser-matrix/logicalparadox.svg)](https://saucelabs.com/u/logicalparadox) 71 | 72 | Look for the list of browsers/versions to expand over the coming releases. 73 | 74 | - [#195](https://github.com/chaijs/chai/issues/195) karma test framework 75 | 76 | ## 1.7.2 / 2013-06-27 77 | 78 | The following changes are required if you are upgrading from the previous version: 79 | 80 | - **Users:** 81 | - No changes required. 82 | - **Plugin Developers:** 83 | - No changes required 84 | - **Core Contributors:** 85 | - Refresh `node_modules` folder for updated dependencies. 86 | 87 | ### Coverage Reporting 88 | 89 | Coverage reporting has always been available for core-developers but the data has never been published 90 | for our end users. In our ongoing effort to improve accountability this data will now be published via 91 | the [coveralls.io](https://coveralls.io/) service. A badge has been added to the README and the full report 92 | can be viewed online at the [chai coveralls project](https://coveralls.io/r/chaijs/chai). Furthermore, PRs 93 | will receive automated messages indicating how their PR impacts test coverage. This service is tied to TravisCI. 94 | 95 | ### Other Fixes 96 | 97 | - [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. (Fix ignore all) 98 | 99 | ## 1.7.1 / 2013-06-24 100 | 101 | The following changes are required if you are upgrading from the previous version: 102 | 103 | - **Users:** 104 | - No changes required. 105 | - **Plugin Developers:** 106 | - No changes required 107 | - **Core Contributors:** 108 | - Refresh `node_modules` folder for updated dependencies. 109 | 110 | ### Official Bower Support 111 | 112 | Support has been added for the Bower Package Manager ([bower.io])(http://bower.io/). Though 113 | Chai could be installed via Bower in the past, this update adds official support via the `bower.json` 114 | specification file. 115 | 116 | - [#175](https://github.com/chaijs/chai/issues/175) Add `bower.json`. 117 | 118 | ## 1.7.0 / 2013-06-17 119 | 120 | The following changes are required if you are upgrading from the previous version: 121 | 122 | - **Users:** 123 | - No changes required. 124 | - **Plugin Developers:** 125 | - Review AssertionError update notice. 126 | - **Core Contributors:** 127 | - Refresh `node_modules` folder for updated dependencies. 128 | 129 | ### AssertionError Update Notice 130 | 131 | Chai now uses [chaijs/assertion-error](https://github.com/chaijs/assertion-error) instead an internal 132 | constructor. This will allow for further iteration/experimentation of the AssertionError constructor 133 | independant of Chai. Future plans include stack parsing for callsite support. 134 | 135 | This update constructor has a different constructor param signature that conforms more with the standard 136 | `Error` object. If your plugin throws and `AssertionError` directly you will need to update your plugin 137 | with the new signature. 138 | 139 | ```js 140 | var AssertionError = require('chai').AssertionError; 141 | 142 | /** 143 | * previous 144 | * 145 | * @param {Object} options 146 | */ 147 | 148 | throw new AssertionError({ 149 | message: 'An assertion error occurred' 150 | , actual: actual 151 | , expect: expect 152 | , startStackFunction: arguments.callee 153 | , showStack: true 154 | }); 155 | 156 | /** 157 | * new 158 | * 159 | * @param {String} message 160 | * @param {Object} options 161 | * @param {Function} start stack function 162 | */ 163 | 164 | throw new AssertionError('An assertion error occurred', { 165 | actual: actual 166 | , expect: expect 167 | , showStack: true 168 | }, arguments.callee); 169 | 170 | // other signatures 171 | throw new AssertionError('An assertion error occurred'); 172 | throw new AssertionError('An assertion error occurred', null, arguments.callee); 173 | ``` 174 | 175 | #### External Dependencies 176 | 177 | This is the first non-developement dependency for Chai. As Chai continues to evolve we will begin adding 178 | more; the next will likely be improved type detection and deep equality. With Chai's userbase continually growing 179 | there is an higher need for accountability and documentation. External dependencies will allow us to iterate and 180 | test on features independent from our interfaces. 181 | 182 | Note: The browser packaged version `chai.js` will ALWAYS contain all dependencies needed to run Chai. 183 | 184 | ### Community Contributions 185 | 186 | - [#169](https://github.com/chaijs/chai/pull/169) Fix deep equal comparison for Date/Regexp types. [@katsgeorgeek](https://github.com/katsgeorgeek) 187 | - [#171](https://github.com/chaijs/chai/pull/171) Add `assert.notOk()`. [@Bartvds](https://github.com/Bartvds) 188 | - [#173](https://github.com/chaijs/chai/pull/173) Fix `inspect` utility. [@domenic](https://github.com/domenic) 189 | 190 | Thank you to all who took the time to contribute! 191 | 192 | ## 1.6.1 / 2013-06-05 193 | 194 | The following changes are required if you are upgrading from the previous version: 195 | 196 | - **Users:** 197 | - No changes required. 198 | - **Plugin Developers:** 199 | - No changes required. 200 | - **Core Contributors:** 201 | - Refresh `node_modules` folder for updated developement dependencies. 202 | 203 | ### Deep Equality 204 | 205 | Regular Expressions are now tested as part of all deep equality assertions. In previous versions 206 | they silently passed for all scenarios. Thanks to [@katsgeorgeek](https://github.com/katsgeorgeek) for the contribution. 207 | 208 | ### Community Contributions 209 | 210 | - [#161](https://github.com/chaijs/chai/pull/161) Fix documented name for assert interface's isDefined method. [@brandonpayton](https://github.com/brandonpayton) 211 | - [#168](https://github.com/chaijs/chai/pull/168) Fix comparison equality of two regexps for when using deep equality. [@katsgeorgeek](https://github.com/katsgeorgeek) 212 | 213 | Thank you to all who took the time to contribute! 214 | 215 | ### Additional Notes 216 | 217 | - Mocha has been locked at version `1.8.x` to ensure `mocha-phantomjs` compatibility. 218 | 219 | ## 1.6.0 / 2013-04-29 220 | 221 | The following changes are required if you are upgrading from the previous version: 222 | 223 | - **Users:** 224 | - No changes required. 225 | - **Plugin Developers:** 226 | - No changes required. 227 | - **Core Contributors:** 228 | - Refresh `node_modules` folder for updated developement dependencies. 229 | 230 | ### New Assertions 231 | 232 | #### Array Members Inclusion 233 | 234 | Asserts that the target is a superset of `set`, or that the target and `set` have the same members. 235 | Order is not taken into account. Thanks to [@NickHeiner](https://github.com/NickHeiner) for the contribution. 236 | 237 | ```js 238 | // (expect/should) full set 239 | expect([4, 2]).to.have.members([2, 4]); 240 | expect([5, 2]).to.not.have.members([5, 2, 1]); 241 | 242 | // (expect/should) inclusion 243 | expect([1, 2, 3]).to.include.members([3, 2]); 244 | expect([1, 2, 3]).to.not.include.members([3, 2, 8]); 245 | 246 | // (assert) full set 247 | assert.sameMembers([ 1, 2, 3 ], [ 2, 1, 3 ], 'same members'); 248 | 249 | // (assert) inclusion 250 | assert.includeMembers([ 1, 2, 3 ], [ 2, 1 ], 'include members'); 251 | 252 | ``` 253 | 254 | #### Non-inclusion for Assert Interface 255 | 256 | Most `assert` functions have a negative version, like `instanceOf()` has a corresponding `notInstaceOf()`. 257 | However `include()` did not have a corresponding `notInclude()`. This has been added. 258 | 259 | ```js 260 | assert.notInclude([ 1, 2, 3 ], 8); 261 | assert.notInclude('foobar', 'baz'); 262 | ``` 263 | 264 | ### Community Contributions 265 | 266 | - [#140](https://github.com/chaijs/chai/pull/140) Restore `call`/`apply` methods for plugin interface. [@RubenVerborgh](https://github.com/RubenVerborgh) 267 | - [#148](https://github.com/chaijs/chai/issues/148)/[#153](https://github.com/chaijs/chai/pull/153) Add `members` and `include.members` assertions. [#NickHeiner](https://github.com/NickHeiner) 268 | 269 | Thank you to all who took time to contribute! 270 | 271 | ### Other Bug Fixes 272 | 273 | - [#142](https://github.com/chaijs/chai/issues/142) `assert#include` will no longer silently pass on wrong-type haystack. 274 | - [#158](https://github.com/chaijs/chai/issues/158) `assert#notInclude` has been added. 275 | - Travis-CI now tests Node.js `v0.10.x`. Support for `v0.6.x` has been removed. `v0.8.x` is still tested as before. 276 | 277 | ## 1.5.0 / 2013-02-03 278 | 279 | ### Migration Requirements 280 | 281 | The following changes are required if you are upgrading from the previous version: 282 | 283 | - **Users:** 284 | - _Update [2013-02-04]:_ Some users may notice a small subset of deep equality assertions will no longer pass. This is the result of 285 | [#120](https://github.com/chaijs/chai/issues/120), an improvement to our deep equality algorithm. Users will need to revise their assertions 286 | to be more granular should this occur. Further information: [#139](https://github.com/chaijs/chai/issues/139). 287 | - **Plugin Developers:** 288 | - No changes required. 289 | - **Core Contributors:** 290 | - Refresh `node_modules` folder for updated developement dependencies. 291 | 292 | ### Community Contributions 293 | 294 | - [#126](https://github.com/chaijs/chai/pull/126): Add `eqls` alias for `eql`. [@RubenVerborgh](https://github.com/RubenVerborgh) 295 | - [#127](https://github.com/chaijs/chai/issues/127): Performance refactor for chainable methods. [@RubenVerborgh](https://github.com/RubenVerborgh) 296 | - [#133](https://github.com/chaijs/chai/pull/133): Assertion `.throw` support for primitives. [@RubenVerborgh](https://github.com/RubenVerborgh) 297 | - [#137](https://github.com/chaijs/chai/issues/137): Assertion `.throw` support for empty messages. [@timnew](https://github.com/timnew) 298 | - [#136](https://github.com/chaijs/chai/pull/136): Fix backward negation messages when using `.above()` and `.below()`. [@whatthejeff](https://github.com/whatthejeff) 299 | 300 | Thank you to all who took time to contribute! 301 | 302 | ### Other Bug Fixes 303 | 304 | - Improve type detection of `.a()`/`.an()` to work in cross-browser scenarios. 305 | - [#116](https://github.com/chaijs/chai/issues/116): `.throw()` has cleaner display of errors when WebKit browsers. 306 | - [#120](https://github.com/chaijs/chai/issues/120): `.eql()` now works to compare dom nodes in browsers. 307 | 308 | 309 | ### Usage Updates 310 | 311 | #### For Users 312 | 313 | **1. Component Support:** Chai now included the proper configuration to be installed as a 314 | [component](https://github.com/component/component). Component users are encouraged to consult 315 | [chaijs.com](http://chaijs.com) for the latest version number as using the master branch 316 | does not gaurantee stability. 317 | 318 | ```js 319 | // relevant component.json 320 | devDependencies: { 321 | "chaijs/chai": "1.5.0" 322 | } 323 | ``` 324 | 325 | Alternatively, bleeding-edge is available: 326 | 327 | $ component install chaijs/chai 328 | 329 | **2. Configurable showDiff:** Some test runners (such as [mocha](http://visionmedia.github.com/mocha/)) 330 | include support for showing the diff of strings and objects when an equality error occurs. Chai has 331 | already included support for this, however some users may not prefer this display behavior. To revert to 332 | no diff display, the following configuration is available: 333 | 334 | ```js 335 | chai.Assertion.showDiff = false; // diff output disabled 336 | chai.Assertion.showDiff = true; // default, diff output enabled 337 | ``` 338 | 339 | #### For Plugin Developers 340 | 341 | **1. New Utility - type**: The new utility `.type()` is available as a better implementation of `typeof` 342 | that can be used cross-browser. It handles the inconsistencies of Array, `null`, and `undefined` detection. 343 | 344 | - **@param** _{Mixed}_ object to detect type of 345 | - **@return** _{String}_ object type 346 | 347 | ```js 348 | chai.use(function (c, utils) { 349 | // some examples 350 | utils.type({}); // 'object' 351 | utils.type(null); // `null' 352 | utils.type(undefined); // `undefined` 353 | utils.type([]); // `array` 354 | }); 355 | ``` 356 | 357 | #### For Core Contributors 358 | 359 | **1. Browser Testing**: Browser testing of the `./chai.js` file is now available in the command line 360 | via PhantomJS. `make test` and Travis-CI will now also rebuild and test `./chai.js`. Consequently, all 361 | pull requests will now be browser tested in this way. 362 | 363 | _Note: Contributors opening pull requests should still NOT include the browser build._ 364 | 365 | **2. SauceLabs Testing**: Early SauceLab support has been enabled with the file `./support/mocha-cloud.js`. 366 | Those interested in trying it out should create a free [Open Sauce](https://saucelabs.com/signup/plan) account 367 | and include their credentials in `./test/auth/sauce.json`. 368 | -------------------------------------------------------------------------------- /bower_components/mocha/History.md: -------------------------------------------------------------------------------- 1 | 2 | 1.14.0 / 2013-11-02 3 | ================== 4 | 5 | * add: unified diff (#862) 6 | * add: set MOCHA_COLORS env var to use colors (#965) 7 | * add: able to override tests links in html reporters (#776) 8 | * remove: teamcity reporter (#954) 9 | * update: commander dependency to 2.0.0 (#1010) 10 | * fix: mocha --ui will try to require the ui if not built in, as --reporter does (#1022) 11 | * fix: send cursor commands only if isatty (#184, #1003) 12 | * fix: include assertion message in base reporter (#993, #991) 13 | * fix: consistent return of it, it.only, and describe, describe.only (#840) 14 | 15 | 1.13.0 / 2013-09-15 16 | ================== 17 | 18 | * add: sort test files with --sort (#813) 19 | * update: diff depedency to 1.0.7 20 | * update: glob dependency to 3.2.3 (#927) 21 | * fix: diffs show whitespace differences (#976) 22 | * fix: improve global leaks (#783) 23 | * fix: firefox window.getInterface leak 24 | * fix: accessing iframe via window[iframeIndex] leak 25 | * fix: faster global leak checking 26 | * fix: reporter pending css selector (#970) 27 | 28 | 1.12.1 / 2013-08-29 29 | ================== 30 | 31 | * remove test.js from .gitignore 32 | * update included version of ms.js 33 | 34 | 1.12.0 / 2013-07-01 35 | ================== 36 | 37 | * add: prevent diffs for differing types. Closes #900 38 | * add `Mocha.process` hack for phantomjs 39 | * fix: use compilers with requires 40 | * fix regexps in diffs. Closes #890 41 | * fix xunit NaN on failure. Closes #894 42 | * fix: strip tab indentation in `clean` utility method 43 | * fix: textmate bundle installation 44 | 45 | 1.11.0 / 2013-06-12 46 | ================== 47 | 48 | * add --prof support 49 | * add --harmony support 50 | * add --harmony-generators support 51 | * add "Uncaught " prefix to uncaught exceptions 52 | * add web workers support 53 | * add `suite.skip()` 54 | * change to output # of pending / passing even on failures. Closes #872 55 | * fix: prevent hooks from being called if we are bailing 56 | * fix `this.timeout(0)` 57 | 58 | 1.10.0 / 2013-05-21 59 | ================== 60 | 61 | * add add better globbing support for windows via `glob` module 62 | * add support to pass through flags such as --debug-brk=1234. Closes #852 63 | * add test.only, test.skip to qunit interface 64 | * change to always use word-based diffs for now. Closes #733 65 | * change `mocha init` tests.html to index.html 66 | * fix `process` global leak in the browser 67 | * fix: use resolve() instead of join() for --require 68 | * fix: filterLeaks() condition to not consider indices in global object as leaks 69 | * fix: restrict mocha.css styling to #mocha id 70 | * fix: save timer references to avoid Sinon interfering in the browser build. 71 | 72 | 1.9.0 / 2013-04-03 73 | ================== 74 | 75 | * add improved setImmediate implementation 76 | * replace --ignore-leaks with --check-leaks 77 | * change default of ignoreLeaks to true. Closes #791 78 | * remove scrolling for HTML reporter 79 | * fix retina support 80 | * fix tmbundle, restrict to js scope 81 | 82 | 1.8.2 / 2013-03-11 83 | ================== 84 | 85 | * add `setImmediate` support for 0.10.x 86 | * fix mocha -w spinner on windows 87 | 88 | 1.8.1 / 2013-01-09 89 | ================== 90 | 91 | * fix .bail() arity check causing it to default to true 92 | 93 | 1.8.0 / 2013-01-08 94 | ================== 95 | 96 | * add Mocha() options bail support 97 | * add `Mocha#bail()` method 98 | * add instanceof check back for inheriting from Error 99 | * add component.json 100 | * add diff.js to browser build 101 | * update growl 102 | * fix TAP reporter failures comment :D 103 | 104 | 1.7.4 / 2012-12-06 105 | ================== 106 | 107 | * add total number of passes and failures to TAP 108 | * remove .bind() calls. re #680 109 | * fix indexOf. Closes #680 110 | 111 | 1.7.3 / 2012-11-30 112 | ================== 113 | 114 | * fix uncaught error support for the browser 115 | * revert uncaught "fix" which breaks node 116 | 117 | 1.7.2 / 2012-11-28 118 | ================== 119 | 120 | * fix uncaught errors to expose the original error message 121 | 122 | 1.7.0 / 2012-11-07 123 | ================== 124 | 125 | * add `--async-only` support to prevent false positives for missing `done()` 126 | * add sorting by filename in code coverage 127 | * add HTML 5 doctype to browser template. 128 | * add play button to html reporter to rerun a single test 129 | * add `this.timeout(ms)` as Suite#timeout(ms). Closes #599 130 | * update growl dependency to 1.6.x 131 | * fix encoding of test-case ?grep. Closes #637 132 | * fix unicode chars on windows 133 | * fix dom globals in Opera/IE. Closes #243 134 | * fix markdown reporter a tags 135 | * fix `this.timeout("5s")` support 136 | 137 | 1.6.0 / 2012-10-02 138 | ================== 139 | 140 | * add object diffs when `err.showDiff` is present 141 | * add hiding of empty suites when pass/failures are toggled 142 | * add faster `.length` checks to `checkGlobals()` before performing the filter 143 | 144 | 1.5.0 / 2012-09-21 145 | ================== 146 | 147 | * add `ms()` to `.slow()` and `.timeout()` 148 | * add `Mocha#checkLeaks()` to re-enable global leak checks 149 | * add `this.slow()` option [aheckmann] 150 | * add tab, CR, LF to error diffs for now 151 | * add faster `.checkGlobals()` solution [guille] 152 | * remove `fn.call()` from reduce util 153 | * remove `fn.call()` from filter util 154 | * fix forEach. Closes #582 155 | * fix relaying of signals [TooTallNate] 156 | * fix TAP reporter grep number 157 | 158 | 1.4.2 / 2012-09-01 159 | ================== 160 | 161 | * add support to multiple `Mocha#globals()` calls, and strings 162 | * add `mocha.reporter()` constructor support [jfirebaugh] 163 | * add `mocha.timeout()` 164 | * move query-string parser to utils.js 165 | * move highlight code to utils.js 166 | * fix third-party reporter support [exogen] 167 | * fix client-side API to match node-side [jfirebaugh] 168 | * fix mocha in iframe [joliss] 169 | 170 | 1.4.1 / 2012-08-28 171 | ================== 172 | 173 | * add missing `Markdown` export 174 | * fix `Mocha#grep()`, escape regexp strings 175 | * fix reference error when `devicePixelRatio` is not defined. Closes #549 176 | 177 | 1.4.0 / 2012-08-22 178 | ================== 179 | 180 | * add mkdir -p to `mocha init`. Closes #539 181 | * add `.only()`. Closes #524 182 | * add `.skip()`. Closes #524 183 | * change str.trim() to use utils.trim(). Closes #533 184 | * fix HTML progress indicator retina display 185 | * fix url-encoding of click-to-grep HTML functionality 186 | 187 | 1.3.2 / 2012-08-01 188 | ================== 189 | 190 | * fix exports double-execution regression. Closes #531 191 | 192 | 1.3.1 / 2012-08-01 193 | ================== 194 | 195 | * add passes/failures toggling to HTML reporter 196 | * add pending state to `xit()` and `xdescribe()` [Brian Moore] 197 | * add the @charset "UTF-8"; to fix #522 with FireFox. [Jonathan Creamer] 198 | * add border-bottom to #stats links 199 | * add check for runnable in `Runner#uncaught()`. Closes #494 200 | * add 0.4 and 0.6 back to travis.yml 201 | * add `-E, --growl-errors` to growl on failures only 202 | * add prefixes to debug() names. Closes #497 203 | * add `Mocha#invert()` to js api 204 | * change dot reporter to use sexy unicode dots 205 | * fix error when clicking pending test in HTML reporter 206 | * fix `make tm` 207 | 208 | 1.3.0 / 2012-07-05 209 | ================== 210 | 211 | * add window scrolling to `HTML` reporter 212 | * add v8 `--trace-*` option support 213 | * add support for custom reports via `--reporter MODULE` 214 | * add `--invert` switch to invert `--grep` matches 215 | * fix export of `Nyan` reporter. Closes #495 216 | * fix escaping of `HTML` suite titles. Closes #486 217 | * fix `done()` called multiple times with an error test 218 | * change `--grep` - regexp escape the input 219 | 220 | 1.2.2 / 2012-06-28 221 | ================== 222 | 223 | * Added 0.8.0 support 224 | 225 | 1.2.1 / 2012-06-25 226 | ================== 227 | 228 | * Added `this.test.error(err)` support to after each hooks. Closes #287 229 | * Added: export top-level suite on global mocha object (mocha.suite). Closes #448 230 | * Fixed `js` code block format error in markdown reporter 231 | * Fixed deprecation warning when using `path.existsSync` 232 | * Fixed --globals with wildcard 233 | * Fixed chars in nyan when his head moves back 234 | * Remove `--growl` from test/mocha.opts. Closes #289 235 | 236 | 1.2.0 / 2012-06-17 237 | ================== 238 | 239 | * Added `nyan` reporter [Atsuya Takagi] 240 | * Added `mocha init ` to copy client files 241 | * Added "specify" synonym for "it" [domenic] 242 | * Added global leak wildcard support [nathanbowser] 243 | * Fixed runner emitter leak. closes #432 244 | * Fixed omission of .js extension. Closes #454 245 | 246 | 1.1.0 / 2012-05-30 247 | ================== 248 | 249 | * Added: check each `mocha(1)` arg for directories to walk 250 | * Added `--recursive` [tricknotes] 251 | * Added `context` for BDD [hokaccha] 252 | * Added styling for new clickable titles 253 | * Added clickable suite titles to HTML reporter 254 | * Added warning when strings are thrown as errors 255 | * Changed: green arrows again in HTML reporter styling 256 | * Changed ul/li elements instead of divs for better copy-and-pasting [joliss] 257 | * Fixed issue #325 - add better grep support to js api 258 | * Fixed: save timer references to avoid Sinon interfering. 259 | 260 | 1.0.3 / 2012-04-30 261 | ================== 262 | 263 | * Fixed string diff newlines 264 | * Fixed: removed mocha.css target. Closes #401 265 | 266 | 1.0.2 / 2012-04-25 267 | ================== 268 | 269 | * Added HTML reporter duration. Closes #47 270 | * Fixed: one postMessage event listener [exogen] 271 | * Fixed: allow --globals to be used multiple times. Closes #100 [brendannee] 272 | * Fixed #158: removes jquery include from browser tests 273 | * Fixed grep. Closes #372 [brendannee] 274 | * Fixed #166 - When grepping don't display the empty suites 275 | * Removed test/browser/style.css. Closes #385 276 | 277 | 1.0.1 / 2012-04-04 278 | ================== 279 | 280 | * Fixed `.timeout()` in hooks 281 | * Fixed: allow callback for `mocha.run()` in client version 282 | * Fixed browser hook error display. Closes #361 283 | 284 | 1.0.0 / 2012-03-24 285 | ================== 286 | 287 | * Added js API. Closes #265 288 | * Added: initial run of tests with `--watch`. Closes #345 289 | * Added: mark `location` as a global on the CS. Closes #311 290 | * Added `markdown` reporter (github flavour) 291 | * Added: scrolling menu to coverage.html. Closes #335 292 | * Added source line to html report for Safari [Tyson Tate] 293 | * Added "min" reporter, useful for `--watch` [Jakub Nešetřil] 294 | * Added support for arbitrary compilers via . Closes #338 [Ian Young] 295 | * Added Teamcity export to lib/reporters/index [Michael Riley] 296 | * Fixed chopping of first char in error reporting. Closes #334 [reported by topfunky] 297 | * Fixed terrible FF / Opera stack traces 298 | 299 | 0.14.1 / 2012-03-06 300 | ================== 301 | 302 | * Added lib-cov to _.npmignore_ 303 | * Added reporter to `mocha.run([reporter])` as argument 304 | * Added some margin-top to the HTML reporter 305 | * Removed jQuery dependency 306 | * Fixed `--watch`: purge require cache. Closes #266 307 | 308 | 0.14.0 / 2012-03-01 309 | ================== 310 | 311 | * Added string diff support for terminal reporters 312 | 313 | 0.13.0 / 2012-02-23 314 | ================== 315 | 316 | * Added preliminary test coverage support. Closes #5 317 | * Added `HTMLCov` reporter 318 | * Added `JSONCov` reporter [kunklejr] 319 | * Added `xdescribe()` and `xit()` to the BDD interface. Closes #263 (docs * Changed: make json reporter output pretty json 320 | * Fixed node-inspector support, swapped `--debug` for `debug` to match node. 321 | needed) 322 | Closes #247 323 | 324 | 0.12.1 / 2012-02-14 325 | ================== 326 | 327 | * Added `npm docs mocha` support [TooTallNate] 328 | * Added a `Context` object used for hook and test-case this. Closes #253 329 | * Fixed `Suite#clone()` `.ctx` reference. Closes #262 330 | 331 | 0.12.0 / 2012-02-02 332 | ================== 333 | 334 | * Added .coffee `--watch` support. Closes #242 335 | * Added support to `--require` files relative to the CWD. Closes #241 336 | * Added quick n dirty syntax highlighting. Closes #248 337 | * Changed: made HTML progress indicator smaller 338 | * Fixed xunit errors attribute [dhendo] 339 | 340 | 0.10.2 / 2012-01-21 341 | ================== 342 | 343 | * Fixed suite count in reporter stats. Closes #222 344 | * Fixed `done()` after timeout error reporting [Phil Sung] 345 | * Changed the 0-based errors to 1 346 | 347 | 0.10.1 / 2012-01-17 348 | ================== 349 | 350 | * Added support for node 0.7.x 351 | * Fixed absolute path support. Closes #215 [kompiro] 352 | * Fixed `--no-colors` option [Jussi Virtanen] 353 | * Fixed Arial CSS typo in the correct file 354 | 355 | 0.10.0 / 2012-01-13 356 | ================== 357 | 358 | * Added `-b, --bail` to exit on first exception [guillermo] 359 | * Added support for `-gc` / `--expose-gc` [TooTallNate] 360 | * Added `qunit`-inspired interface 361 | * Added MIT LICENSE. Closes #194 362 | * Added: `--watch` all .js in the CWD. Closes #139 363 | * Fixed `self.test` reference in runner. Closes #189 364 | * Fixed double reporting of uncaught exceptions after timeout. Closes #195 365 | 366 | 0.8.2 / 2012-01-05 367 | ================== 368 | 369 | * Added test-case context support. Closes #113 370 | * Fixed exit status. Closes #187 371 | * Update commander. Closes #190 372 | 373 | 0.8.1 / 2011-12-30 374 | ================== 375 | 376 | * Fixed reporting of uncaught exceptions. Closes #183 377 | * Fixed error message defaulting [indutny] 378 | * Changed mocha(1) from bash to node for windows [Nathan Rajlich] 379 | 380 | 0.8.0 / 2011-12-28 381 | ================== 382 | 383 | * Added `XUnit` reporter [FeeFighters/visionmedia] 384 | * Added `say(1)` notification support [Maciej Małecki] 385 | * Changed: fail when done() is invoked with a non-Error. Closes #171 386 | * Fixed `err.stack`, defaulting to message. Closes #180 387 | * Fixed: `make tm` mkdir -p the dest. Closes #137 388 | * Fixed mocha(1) --help bin name 389 | * Fixed `-d` for `--debug` support 390 | 391 | 0.7.1 / 2011-12-22 392 | ================== 393 | 394 | * Removed `mocha-debug(1)`, use `mocha --debug` 395 | * Fixed CWD relative requires 396 | * Fixed growl issue on windows [Raynos] 397 | * Fixed: platform specific line endings [TooTallNate] 398 | * Fixed: escape strings in HTML reporter. Closes #164 399 | 400 | 0.7.0 / 2011-12-18 401 | ================== 402 | 403 | * Added support for IE{7,8} [guille] 404 | * Changed: better browser nextTick implementation [guille] 405 | 406 | 0.6.0 / 2011-12-18 407 | ================== 408 | 409 | * Added setZeroTimeout timeout for browser (nicer stack traces). Closes #153 410 | * Added "view source" on hover for HTML reporter to make it obvious 411 | * Changed: replace custom growl with growl lib 412 | * Fixed duplicate reporting for HTML reporter. Closes #154 413 | * Fixed silent hook errors in the HTML reporter. Closes #150 414 | 415 | 0.5.0 / 2011-12-14 416 | ================== 417 | 418 | * Added: push node_modules directory onto module.paths for relative require Closes #93 419 | * Added teamcity reporter [blindsey] 420 | * Fixed: recover from uncaught exceptions for tests. Closes #94 421 | * Fixed: only emit "test end" for uncaught within test, not hook 422 | 423 | 0.4.0 / 2011-12-14 424 | ================== 425 | 426 | * Added support for test-specific timeouts via `this.timeout(0)`. Closes #134 427 | * Added guillermo's client-side EventEmitter. Closes #132 428 | * Added progress indicator to the HTML reporter 429 | * Fixed slow browser tests. Closes #135 430 | * Fixed "suite" color for light terminals 431 | * Fixed `require()` leak spotted by [guillermo] 432 | 433 | 0.3.6 / 2011-12-09 434 | ================== 435 | 436 | * Removed suite merging (for now) 437 | 438 | 0.3.5 / 2011-12-08 439 | ================== 440 | 441 | * Added support for `window.onerror` [guillermo] 442 | * Fixed: clear timeout on uncaught exceptions. Closes #131 [guillermo] 443 | * Added `mocha.css` to PHONY list. 444 | * Added `mocha.js` to PHONY list. 445 | 446 | 0.3.4 / 2011-12-08 447 | ================== 448 | 449 | * Added: allow `done()` to be called with non-Error 450 | * Added: return Runner from `mocha.run()`. Closes #126 451 | * Fixed: run afterEach even on failures. Closes #125 452 | * Fixed clobbering of current runnable. Closes #121 453 | 454 | 0.3.3 / 2011-12-08 455 | ================== 456 | 457 | * Fixed hook timeouts. Closes #120 458 | * Fixed uncaught exceptions in hooks 459 | 460 | 0.3.2 / 2011-12-05 461 | ================== 462 | 463 | * Fixed weird reporting when `err.message` is not present 464 | 465 | 0.3.1 / 2011-12-04 466 | ================== 467 | 468 | * Fixed hook event emitter leak. Closes #117 469 | * Fixed: export `Spec` constructor. Closes #116 470 | 471 | 0.3.0 / 2011-12-04 472 | ================== 473 | 474 | * Added `-w, --watch`. Closes #72 475 | * Added `--ignore-leaks` to ignore global leak checking 476 | * Added browser `?grep=pattern` support 477 | * Added `--globals ` to specify accepted globals. Closes #99 478 | * Fixed `mocha-debug(1)` on some systems. Closes #232 479 | * Fixed growl total, use `runner.total` 480 | 481 | 0.2.0 / 2011-11-30 482 | ================== 483 | 484 | * Added `--globals ` to specify accepted globals. Closes #99 485 | * Fixed funky highlighting of messages. Closes #97 486 | * Fixed `mocha-debug(1)`. Closes #232 487 | * Fixed growl total, use runner.total 488 | 489 | 0.1.0 / 2011-11-29 490 | ================== 491 | 492 | * Added `suiteSetup` and `suiteTeardown` to TDD interface [David Henderson] 493 | * Added growl icons. Closes #84 494 | * Fixed coffee-script support 495 | 496 | 0.0.8 / 2011-11-25 497 | ================== 498 | 499 | * Fixed: use `Runner#total` for accurate reporting 500 | 501 | 0.0.7 / 2011-11-25 502 | ================== 503 | 504 | * Added `Hook` 505 | * Added `Runnable` 506 | * Changed: `Test` is `Runnable` 507 | * Fixed global leak reporting in hooks 508 | * Fixed: > 2 calls to done() only report the error once 509 | * Fixed: clear timer on failure. Closes #80 510 | 511 | 0.0.6 / 2011-11-25 512 | ================== 513 | 514 | * Fixed return on immediate async error. Closes #80 515 | 516 | 0.0.5 / 2011-11-24 517 | ================== 518 | 519 | * Fixed: make mocha.opts whitespace less picky [kkaefer] 520 | 521 | 0.0.4 / 2011-11-24 522 | ================== 523 | 524 | * Added `--interfaces` 525 | * Added `--reporters` 526 | * Added `-c, --colors`. Closes #69 527 | * Fixed hook timeouts 528 | 529 | 0.0.3 / 2011-11-23 530 | ================== 531 | 532 | * Added `-C, --no-colors` to explicitly disable 533 | * Added coffee-script support 534 | 535 | 0.0.2 / 2011-11-22 536 | ================== 537 | 538 | * Fixed global leak detection due to Safari bind() change 539 | * Fixed: escape html entities in Doc reporter 540 | * Fixed: escape html entities in HTML reporter 541 | * Fixed pending test support for HTML reporter. Closes #66 542 | 543 | 0.0.1 / 2011-11-22 544 | ================== 545 | 546 | * Added `--timeout` second shorthand support, ex `--timeout 3s`. 547 | * Fixed "test end" event for uncaughtExceptions. Closes #61 548 | 549 | 0.0.1-alpha6 / 2011-11-19 550 | ================== 551 | 552 | * Added travis CI support (needs enabling when public) 553 | * Added preliminary browser support 554 | * Added `make mocha.css` target. Closes #45 555 | * Added stack trace to TAP errors. Closes #52 556 | * Renamed tearDown to teardown. Closes #49 557 | * Fixed: cascading hooksc. Closes #30 558 | * Fixed some colors for non-tty 559 | * Fixed errors thrown in sync test-cases due to nextTick 560 | * Fixed Base.window.width... again give precedence to 0.6.x 561 | 562 | 0.0.1-alpha5 / 2011-11-17 563 | ================== 564 | 565 | * Added `doc` reporter. Closes #33 566 | * Added suite merging. Closes #28 567 | * Added TextMate bundle and `make tm`. Closes #20 568 | 569 | 0.0.1-alpha4 / 2011-11-15 570 | ================== 571 | 572 | * Fixed getWindowSize() for 0.4.x 573 | 574 | 0.0.1-alpha3 / 2011-11-15 575 | ================== 576 | 577 | * Added `-s, --slow ` to specify "slow" test threshold 578 | * Added `mocha-debug(1)` 579 | * Added `mocha.opts` support. Closes #31 580 | * Added: default [files] to _test/*.js_ 581 | * Added protection against multiple calls to `done()`. Closes #35 582 | * Changed: bright yellow for slow Dot reporter tests 583 | 584 | 0.0.1-alpha1 / 2011-11-08 585 | ================== 586 | 587 | * Missed this one :) 588 | 589 | 0.0.1-alpha1 / 2011-11-08 590 | ================== 591 | 592 | * Initial release 593 | -------------------------------------------------------------------------------- /bower_components/chai/History.md: -------------------------------------------------------------------------------- 1 | 2 | 1.8.1 / 2013-10-10 3 | ================== 4 | 5 | * pkg: update deep-eql version 6 | 7 | 1.8.0 / 2013-09-18 8 | ================== 9 | 10 | * test: [sauce] add a few more browsers 11 | * Merge branch 'refactor/deep-equal' 12 | * util: remove embedded deep equal utility 13 | * util: replace embedded deep equal with external module 14 | * Merge branch 'feature/karma' 15 | * docs: add sauce badge to readme [ci skip] 16 | * test: [sauce] use karma@canary to prevent timeouts 17 | * travis: only run on node 0.10 18 | * test: [karma] use karma phantomjs runner 19 | * Merge pull request #181 from tricknotes/fix-highlight 20 | * Fix highlight for example code 21 | 22 | 1.7.2 / 2013-06-27 23 | ================== 24 | 25 | * coverage: add coveralls badge 26 | * test: [coveralls] add coveralls api integration. testing travis-ci integration 27 | * Merge branch 'master' of github.com:chaijs/chai 28 | * Merge branch 'feature/bower' 29 | * Merge pull request #180 from tricknotes/modify-method-title 30 | * Merge pull request #179 from tricknotes/highlight-code-example 31 | * Modify method title to include argument name 32 | * Fix to highlight code example 33 | * bower: granular ignores 34 | 35 | 1.7.1 / 2013-06-24 36 | ================== 37 | 38 | * Merge branch 'feature/bower'. #175 39 | * bower: add json file 40 | * build: browser 41 | 42 | 1.7.0 / 2013-06-17 43 | ================== 44 | 45 | * error: remove internal assertion error constructor 46 | * core: [assertion-error] replace internal assertion error with dep 47 | * deps: add chaijs/assertion-error@1.0.0 48 | * docs: fix typo in source file. #174 49 | * Merge pull request #174 from piecioshka/master 50 | * typo 51 | * Merge branch 'master' of github.com:chaijs/chai 52 | * pkg: lock mocha/mocha-phantomjs versions (for now) 53 | * Merge pull request #173 from chaijs/inspect-fix 54 | * Fix `utils.inspect` with custom object-returning inspect()s. 55 | * Merge pull request #171 from Bartvds/master 56 | * replaced tabs with 2 spaces 57 | * added assert.notOk() 58 | * Merge pull request #169 from katsgeorgeek/topics/master 59 | * Fix comparison objects. 60 | 61 | 1.6.1 / 2013-06-05 62 | ================== 63 | 64 | * Merge pull request #168 from katsgeorgeek/topics/master 65 | * Add test for different RegExp flags. 66 | * Add test for regexp comparison. 67 | * Downgrade mocha version for fix running Phantom tests. 68 | * Fix comparison equality of two regexps. 69 | * Merge pull request #161 from brandonpayton/master 70 | * Fix documented name for assert interfaces isDefined method 71 | 72 | 1.6.0 / 2013-04-29 73 | ================== 74 | 75 | * build: browser 76 | * assert: [(not)include] throw on incompatible haystack. Closes #142 77 | * assert: [notInclude] add assert.notInclude. Closes #158 78 | * browser build 79 | * makefile: force browser build on browser-test 80 | * makefile: use component for browser build 81 | * core: [assertions] remove extraneous comments 82 | * Merge branch 'master' of github.com:chaijs/chai 83 | * test: [assert] deep equal ordering 84 | * Merge pull request #153 from NickHeiner/array-assertions 85 | * giving members a no-flag assertion 86 | * Code review comments - changing syntax 87 | * Code review comments 88 | * Adding members and memberEquals assertions for checking for subsets and set equality. Implements chaijs/chai#148. 89 | * Merge pull request #140 from RubenVerborgh/function-prototype 90 | * Restore the `call` and `apply` methods of Function when adding a chainable method. 91 | * readme: 2013 92 | * notes: migration notes for deep equal changes 93 | * test: for ever err() there must be a passing version 94 | 95 | 1.5.0 / 2013-02-03 96 | ================== 97 | 98 | * docs: add Release Notes for non-gitlog summary of changes. 99 | * lib: update copyright to 2013 100 | * Merge branch 'refactor/travis' 101 | * makefile: remove test-component for full test run 102 | * pkg: script test now runs make test so travis will test browser 103 | * browser: build 104 | * tests: refactor some tests to support new objDisplay output 105 | * test: [bootstrap] normalize boostrap across all test scenarios 106 | * assertions: refactor some assertions to use objDisplay instead of inspect 107 | * util: [objDisplay] normalize output of functions 108 | * makefile: refactor for full build scenarios 109 | * component: fix build bug where missing util:type file 110 | * assertions: [throw] code cleanup 111 | * Merge branch 'refactor/typeDetection' 112 | * browser: build 113 | * makefile: chai.js is .PHONY so it builds every time 114 | * test: [expect] add arguments type detection test 115 | * core/assertions: [type] (a/an) refactor to use type detection utility 116 | * util: add cross-browser type detection utility 117 | * Merge branch 'feature/component' 118 | * browser: build 119 | * component: add component.json file 120 | * makefile: refactor for fine grain control of testing scenarios 121 | * test: add mochaPhantomJS support and component test file 122 | * deps: add component and mocha-phantomjs for browser testing 123 | * ignore: update ignore files for component support 124 | * travis: run for all branches 125 | * Merge branch 'feature/showDiff' 126 | * test: [Assertion] configruable showDiff flag. Closes #132 127 | * lib: [Assertion] add configurable showDiff flag. #132 128 | * Merge branch 'feature/saucelabs' 129 | * Merge branch 'master' into feature/saucelabs 130 | * browser: build 131 | * support: add mocha cloud runner, client, and html test page 132 | * test: [saucelabs] add auth placeholder 133 | * deps: add mocha-cloud 134 | * Merge pull request #136 from whatthejeff/message_fix 135 | * Merge pull request #138 from timnew/master 136 | * Fix issue #137, test message existence by using message!=null rather than using message 137 | * Fixed backwards negation messages. 138 | * Merge pull request #133 from RubenVerborgh/throw 139 | * Functions throwing strings can reliably be tested. 140 | * Merge pull request #131 from RubenVerborgh/proto 141 | * Cache whether __proto__ is supported. 142 | * Use __proto__ if available. 143 | * Determine the property names to exclude beforehand. 144 | * Merge pull request #126 from RubenVerborgh/eqls 145 | * Add alias eqls for eql. 146 | * Use inherited enumerable properties in deep equality comparison. 147 | * Show inherited properties when inspecting an object. 148 | * Add new getProperties and getEnumerableProperties utils. 149 | * showDiff: force true for equal and eql 150 | 151 | 1.4.2 / 2012-12-21 152 | ================== 153 | 154 | * browser build: (object diff support when used with mocha) #106 155 | * test: [display] array test for mocha object diff 156 | * browser: no longer need different AssertionError constructor 157 | 158 | 1.4.1 / 2012-12-21 159 | ================== 160 | 161 | * showDiff: force diff for equal and eql. #106 162 | * test: [expect] type null. #122 163 | * Merge pull request #115 from eshao/fix-assert-Throw 164 | * FIX: assert.Throw checks error type/message 165 | * TST: assert.Throw should check error type/message 166 | 167 | 1.4.0 / 2012-11-29 168 | ================== 169 | 170 | * pre-release browser build 171 | * clean up index.js to not check for cov, revert package.json to use index.js 172 | * convert tests to use new bootstrap 173 | * refactor testing bootstrap 174 | * use spaces (not tabs). Clean up #114 175 | * Merge pull request #114 from trantorLiu/master 176 | * Add most() (alias: lte) and least() (alias: gte) to the API with new chainers "at" and "of". 177 | * Change `main` to ./lib/chai. Fixes #28. 178 | * Merge pull request #104 from connec/deep_equals_circular_references_ 179 | * Merge pull request #109 from nnarhinen/patch-1 180 | * Check for 'actual' type 181 | * Added support for circular references when checking deep (in)equality. 182 | 183 | 1.3.0 / 2012-10-01 184 | ================== 185 | 186 | * browser build w/ folio >= 0.3.4. Closes #99 187 | * add back buffer test for deep equal 188 | * do not write flags to assertion.prototype 189 | * remove buffer test from expect 190 | * browser build 191 | * improve documentation of custom error messages 192 | * Merge branch 'master' of git://github.com/Liffft/chai into Liffft-master 193 | * browser build 194 | * improved buffer deep equal checking 195 | * mocha is npm test command 196 | * Cleaning up the js style… 197 | * expect tests now include message pass-through 198 | * packaging up browser-side changes… 199 | * Increasing Throws error message verbosity 200 | * Should syntax: piping message through 201 | * Make globalShould test work in browser too. 202 | * Add a setter for `Object.prototype.should`. Closes #86. 203 | 204 | 1.2.0 / 2012-08-07 205 | ================== 206 | 207 | * Merge branch 'feature/errmsg' 208 | * browser build 209 | * comment updates for utilities 210 | * tweak objDislay to only kick in if object inspection is too long 211 | * Merge branch 'master' into feature/errmsg 212 | * add display sample for error message refactor 213 | * first draft of error message refactor. #93 214 | * add `closeTo` assertion to `assert` interface. Closes #89. 215 | * update folio build for better require.js handling. Closes #85 216 | * Merge pull request #92 from paulmillr/topics/add-dom-checks 217 | * Add check for DOM objects. 218 | * browser build 219 | * Merge branch 'master' of github.com:chaijs/chai 220 | * bug - getActual not defaulting to assertion subject 221 | * Merge pull request #88 from pwnall/master 222 | * Don't inspect() assertion arguments if the assertion passes. 223 | 224 | 1.1.1 / 2012-07-09 225 | ================== 226 | 227 | * improve commonjs support on browser build 228 | * Merge pull request #83 from tkazec/equals 229 | * Document .equals 230 | * Add .equals as an alias of .equal 231 | * remove unused browser prefix/suffix 232 | * Merge branch 'feature/folio-build' 233 | * browser build 234 | * using folio to compile 235 | * clean up makefile 236 | * early folio 0.3.x support 237 | 238 | 1.1.0 / 2012-06-26 239 | ================== 240 | 241 | * browser build 242 | * Disable "Assertion.includeStack is false" test in IE. 243 | * Use `utils.getName` for all function inspections. 244 | * Merge pull request #80 from kilianc/closeTo 245 | * fixes #79 246 | * browser build 247 | * expand docs to indicate change of subject for chaining. Closes #78 248 | * add `that` chain noop 249 | * Merge branch 'bug/74' 250 | * comments on how to property use `length` as chain. Closes #74 251 | * tests for length as chainable property. #74 252 | * add support for `length` as chainable prop/method. 253 | * Merge branch 'bug/77' 254 | * tests for getPathValue when working with nested arrays. Closes #77 255 | * add getPathValue support for nested arrays 256 | * browser build 257 | * fix bug for missing browser utils 258 | * compile tool aware of new folder layout 259 | * Merge branch 'refactor/1dot1' 260 | * move core assertions to own file and refactor all using utils 261 | * rearrange folder structure 262 | 263 | 1.0.4 / 2012-06-03 264 | ================== 265 | 266 | * Merge pull request #68 from fizker/itself 267 | * Added itself chain. 268 | * simplify error inspections for cross browser compatibility 269 | * fix safari `addChainableMethod` errors. Closes #69 270 | 271 | 1.0.3 / 2012-05-27 272 | ================== 273 | 274 | * Point Travis badge to the right place. 275 | * Make error message for eql/deep.equal more clear. 276 | * Fix .not.deep.equal. 277 | * contributors list 278 | 279 | 1.0.2 / 2012-05-26 280 | ================== 281 | 282 | * Merge pull request #67 from chaijs/chaining-and-flags 283 | * Browser build. 284 | * Use `addChainableMethod` to get away from `__proto__` manipulation. 285 | * New `addChainableMethod` utility. 286 | * Replace `getAllFlags` with `transferFlags` utility. 287 | * browser build 288 | * test - get all flags 289 | * utility - get all flags 290 | * Add .mailmap to .npmignore. 291 | * Add a .mailmap file to fix my name in shortlogs. 292 | 293 | 1.0.1 / 2012-05-18 294 | ================== 295 | 296 | * browser build 297 | * Fixing "an" vs. "a" grammar in type assertions. 298 | * Uniformize `assert` interface inline docs. 299 | * Don't use `instanceof` for `assert.isArray`. 300 | * Add `deep` flag for equality and property value. 301 | * Merge pull request #64 from chaijs/assertion-docs 302 | * Uniformize assertion inline docs. 303 | * Add npm-debug.log to .gitignore. 304 | * no reserved words as actuals. #62 305 | 306 | 1.0.0 / 2012-05-15 307 | ================== 308 | 309 | * readme cleanup 310 | * browser build 311 | * utility comments 312 | * removed docs 313 | * update to package.json 314 | * docs build 315 | * comments / docs updates 316 | * plugins app cleanup 317 | * Merge pull request #61 from joliss/doc 318 | * Fix and improve documentation of assert.equal and friends 319 | * browser build 320 | * doc checkpoint - texture 321 | * Update chai-jquery link 322 | * Use defined return value of Assertion extension functions 323 | * Update utility docs 324 | 325 | 1.0.0-rc3 / 2012-05-09 326 | ================== 327 | 328 | * Merge branch 'feature/rc3' 329 | * docs update 330 | * browser build 331 | * assert test conformity for minor refactor api 332 | * assert minor refactor 333 | * update util tests for new add/overwrite prop/method format 334 | * added chai.Assertion.add/overwrite prop/method for plugin toolbox 335 | * add/overwrite prop/method don't make assumptions about context 336 | * doc test suite 337 | * docs don't need coverage 338 | * refactor all simple chains into one forEach loop, for clean documentation 339 | * updated npm ignore 340 | * remove old docs 341 | * docs checkpoint - guide styled 342 | * Merge pull request #59 from joliss/doc 343 | * Document how to run the test suite 344 | * don't need to rebuild docs to view 345 | * dep update 346 | * docs checkpoint - api section 347 | * comment updates for docs 348 | * new doc site checkpoint - plugin directory! 349 | * Merge pull request #57 from kossnocorp/patch-1 350 | * Fix typo: devDependancies → devDependencies 351 | * Using message flag in `getMessage` util instead of old `msg` property. 352 | * Adding self to package.json contributors. 353 | * `getMessage` shouldn't choke on null/omitted messages. 354 | * `return this` not necessary in example. 355 | * `return this` not necessary in example. 356 | * Sinon–Chai has a dash 357 | * updated plugins list for docs 358 | 359 | 1.0.0-rc2 / 2012-05-06 360 | ================== 361 | 362 | * Merge branch 'feature/test-cov' 363 | * browser build 364 | * missing assert tests for ownProperty 365 | * appropriate assert equivalent for expect.to.have.property(key, val) 366 | * reset AssertionError to include full stack 367 | * test for plugin utilities 368 | * overwrite Property and Method now ensure chain 369 | * version notes in readme 370 | 371 | 1.0.0-rc1 / 2012-05-04 372 | ================== 373 | 374 | * browser build (rc1) 375 | * assert match/notMatch tests 376 | * assert interface - notMatch, ownProperty, notOwnProperty, ownPropertyVal, ownPropertyNotVal 377 | * cleaner should interface export. 378 | * added chai.Assertion.prototype._obj (getter) for quick access to object flag 379 | * moved almostEqual / almostDeepEqual to stats plugin 380 | * added mocha.opts 381 | * Add test for `utils.addMethod` 382 | * Fix a typo 383 | * Add test for `utils.overwriteMethod` 384 | * Fix a typo 385 | * Browser build 386 | * Add undefined assertion 387 | * Add null assertion 388 | * Fix an issue with `mocha --watch` 389 | * travis no longer tests on node 0.4.x 390 | * removing unnecissary carbon dep 391 | * Merge branch 'feature/plugins-app' 392 | * docs build 393 | * templates for docs express app for plugin directory 394 | * express app for plugin and static serving 395 | * added web server deps 396 | * Merge pull request #54 from josher19/master 397 | * Remove old test.assert code 398 | * Use util.inspect instead of inspect for deepAlmostEqual and almostEqual 399 | * browser build 400 | * Added almostEqual and deepAlmostEqual to assert test suite. 401 | * bug - context determinants for utils 402 | * dec=0 means rounding, so assert.deepAlmostEqual({pi: 3.1416}, {pi: 3}, 0) is true 403 | * wrong travis link 404 | * readme updates for version information 405 | * travis tests 0.5.x branch as well 406 | * [bug] util `addProperty` not correctly exporting 407 | * read me version notes 408 | * browser build 1.0.0alpha1 409 | * not using reserved words in internal assertions. #52 410 | * version tick 411 | * clean up redundant tests 412 | * Merge branch 'refs/heads/0.6.x' 413 | * update version tag in package 1.0.0alpha1 414 | * browser build 415 | * added utility tests to browser specs 416 | * beginning utility testing 417 | * updated utility comments 418 | * utility - overwriteMethod 419 | * utility - overwriteProperty 420 | * utility - addMethod 421 | * utility - addProperty 422 | * missing ; 423 | * contributors list update 424 | * Merge branch 'refs/heads/0.6.x-docs' into 0.6.x 425 | * Added guide link to docs. WIP 426 | * Include/contain are now both properties and methods 427 | * Add an alias annotation 428 | * Remove usless function wrapper 429 | * Fix a typo 430 | * A/an are now both properties and methods 431 | * [docs] new site homepage layout / color checkpoint 432 | * Ignore IE-specific error properties. 433 | * Fixing order of error message test. 434 | * New cross-browser `getName` util. 435 | * Fixing up `AssertionError` inheritance. 436 | * backup docs 437 | * Add doctypes 438 | * [bug] was still using `constructor.name` in `throw` assertion 439 | * [bug] flag Object.create(null) instead of new Object 440 | * [test] browser build 441 | * [refactor] all usage of Assertion.prototype.assert now uses template tags and flags 442 | * [refactor] remove Assertion.prototype.inspect for testable object inspection 443 | * [refactor] object to test is now stored in flag, with ssfi and custom message 444 | * [bug] flag util - don't return on `set` 445 | * [docs] comments for getMessage utility 446 | * [feature] getMessage 447 | * [feature] testing utilities 448 | * [refactor] flag doesn't require `call` 449 | * Make order of source files well-defined 450 | * Added support for throw(errorInstance). 451 | * Use a foolproof method of grabbing an error's name. 452 | * Removed constructor.name check from throw. 453 | * disabled stackTrack configuration tests until api is stable again 454 | * first version of line displayed error for node js (unstable) 455 | * refactor core Assertion to use flag utility for negation 456 | * added flag utility 457 | * tests for assert interface negatives. Closed #42 458 | * added assertion negatives that were missing. #42 459 | * Support for expected and actual parameters in assert-style error object 460 | * chai as promised - readme 461 | * Added assert.fail. Closes #40 462 | * better error message for assert.operator. Closes #39 463 | * [refactor] Assertion#property to use getPathValue property 464 | * added getPathValue utility helper 465 | * removed todo about browser build 466 | * version notes 467 | * version bumb 0.6.0 468 | * browser build 469 | * [refactor] browser compile function to replace with `require('./error')' with 'require('./browser/error')' 470 | * [feature] browser uses different error.js 471 | * [refactor] error without chai.fail 472 | * Assertion & interfaces use new utils helper export 473 | * [refactor] primary export for new plugin util usage 474 | * added util index.js helper 475 | * added 2012 to copyright headers 476 | * Added DeepEqual assertions 477 | 478 | 0.5.3 / 2012-04-21 479 | ================== 480 | 481 | * Merge branch 'refs/heads/jgonera-oldbrowsers' 482 | * browser build 483 | * fixed reserved names for old browsers in interface/assert 484 | * fixed reserved names for old browsers in interface/should 485 | * fixed: chai.js no longer contains fail() 486 | * fixed reserved names for old browsers in Assertion 487 | * Merge pull request #49 from joliss/build-order 488 | * Make order of source files well-defined 489 | * Merge pull request #43 from zzen/patch-1 490 | * Support for expected and actual parameters in assert-style error object 491 | * chai as promised - readme 492 | 493 | 0.5.2 / 2012-03-21 494 | ================== 495 | 496 | * browser build 497 | * Merge branch 'feature/assert-fail' 498 | * Added assert.fail. Closes #40 499 | * Merge branch 'bug/operator-msg' 500 | * better error message for assert.operator. Closes #39 501 | * version notes 502 | 503 | 0.5.1 / 2012-03-14 504 | ================== 505 | 506 | * chai.fail no longer exists 507 | * Merge branch 'feature/assertdefined' 508 | * Added asset#isDefined. Closes #37. 509 | * dev docs update for Assertion#assert 510 | 511 | 0.5.0 / 2012-03-07 512 | ================== 513 | 514 | * [bug] on inspect of reg on n 0.4.12 515 | * Merge branch 'bug/33-throws' 516 | * Merge pull request #35 from logicalparadox/empty-object 517 | * browser build 518 | * updated #throw docs 519 | * Assertion#throw `should` tests updated 520 | * Assertion#throw `expect` tests 521 | * Should interface supports multiple throw parameters 522 | * Update Assertion#throw to support strings and type checks. 523 | * Add more tests for `empty` in `should`. 524 | * Add more tests for `empty` in `expect`. 525 | * Merge branch 'master' into empty-object 526 | * don't switch act/exp 527 | * Merge pull request #34 from logicalparadox/assert-operator 528 | * Update the compiled verison. 529 | * Add `assert.operator`. 530 | * Notes on messages. #22 531 | * browser build 532 | * have been test 533 | * below tests 534 | * Merge branch 'feature/actexp' 535 | * browser build 536 | * remove unnecessary fail export 537 | * full support for actual/expected where relevant 538 | * Assertion.assert support expected value 539 | * clean up error 540 | * Update the compiled version. 541 | * Add object & sane arguments support to `Assertion#empty`. 542 | 543 | 0.4.2 / 2012-02-28 544 | ================== 545 | 546 | * fix for `process` not available in browser when used via browserify. Closes #28 547 | * Merge pull request #31 from joliss/doc 548 | * Document that "should" works in browsers other than IE 549 | * Merge pull request #30 from logicalparadox/assert-tests 550 | * Update the browser version of chai. 551 | * Update `assert.doesNotThrow` test in order to check the use case when type is a string. 552 | * Add test for `assert.ifError`. 553 | * Falsey -> falsy. 554 | * Full coverage for `assert.throws` and `assert.doesNotThrow`. 555 | * Add test for `assert.doesNotThrow`. 556 | * Add test for `assert.throws`. 557 | * Add test for `assert.length`. 558 | * Add test for `assert.include`. 559 | * Add test for `assert.isBoolean`. 560 | * Fix the implementation of `assert.isNumber`. 561 | * Add test for `assert.isNumber`. 562 | * Add test for `assert.isString`. 563 | * Add test for `assert.isArray`. 564 | * Add test for `assert.isUndefined`. 565 | * Add test for `assert.isNotNull`. 566 | * Fix `assert.isNotNull` implementation. 567 | * Fix `assert.isNull` implementation. 568 | * Add test for `assert.isNull`. 569 | * Add test for `assert.notDeepEqual`. 570 | * Add test for `assert.deepEqual`. 571 | * Add test for `assert.notStrictEqual`. 572 | * Add test for `assert.strictEqual`. 573 | * Add test for `assert.notEqual`. 574 | 575 | 0.4.1 / 2012-02-26 576 | ================== 577 | 578 | * Merge pull request #27 from logicalparadox/type-fix 579 | * Update the browser version. 580 | * Add should tests for type checks. 581 | * Add function type check test. 582 | * Add more type checks tests. 583 | * Add test for `new Number` type check. 584 | * Fix type of actual checks. 585 | 586 | 0.4.0 / 2012-02-25 587 | ================== 588 | 589 | * docs and readme for upcoming 0.4.0 590 | * docs generated 591 | * putting coverage and tests for docs in docs/out/support 592 | * make docs 593 | * makefile copy necessary resources for tests in docs 594 | * rename configuration test 595 | * Merge pull request #21 from logicalparadox/close-to 596 | * Update the browser version. 597 | * Update `closeTo()` docs. 598 | * Add `Assertion.closeTo()` method. 599 | * Add `.closeTo()` should test. 600 | * Add `.closeTo()` expect test. 601 | * Merge pull request #20 from logicalparadox/satisfy 602 | * Update the browser version. 603 | * `..` -> `()` in `.satisfy()` should test. 604 | * Update example for `.satisfy()`. 605 | * Update the compiled browser version. 606 | * Add `Assertion.satisfy()` method. 607 | * Add `.satisfy()` should test. 608 | * Add `.satisfy()` expect test. 609 | * Merge pull request #19 from logicalparadox/respond-to 610 | * Update the compiled browser version. 611 | * Add `respondTo` Assertion. 612 | * Add `respondTo` should test. 613 | * Add `respondTo` expect test. 614 | * Merge branch 'feature/coverage' 615 | * mocha coverage support 616 | * doc contributors 617 | * README contributors 618 | 619 | 0.3.4 / 2012-02-23 620 | ================== 621 | 622 | * inline comment typos for #15 623 | * Merge branch 'refs/heads/jeffbski-configErrorStackCompat' 624 | * includeStack documentation for all interfaces 625 | * suite name more generic 626 | * Update test to be compatible with browsers that do not support err.stack 627 | * udpated compiled chai.js and added to browser tests 628 | * Allow inclusion of stack trace for Assert error messages to be configurable 629 | * docs sharing buttons 630 | * sinon-chai link 631 | * doc updates 632 | * read me updates include plugins 633 | 634 | 0.3.3 / 2012-02-12 635 | ================== 636 | 637 | * Merge pull request #14 from jfirebaugh/configurable_properties 638 | * Make Assertion.prototype properties configurable 639 | 640 | 0.3.2 / 2012-02-10 641 | ================== 642 | 643 | * codex version 644 | * docs 645 | * docs cleanup 646 | 647 | 0.3.1 / 2012-02-07 648 | ================== 649 | 650 | * node 0.4.x compat 651 | 652 | 0.3.0 / 2012-02-07 653 | ================== 654 | 655 | * Merge branch 'feature/03x' 656 | * browser build 657 | * remove html/json/headers testign 658 | * regex error.message testing 659 | * tests for using plugins 660 | * Merge pull request #11 from domenic/master 661 | * Make `chai.use` a no-op if the function has already been used. 662 | 663 | 0.2.4 / 2012-02-02 664 | ================== 665 | 666 | * added in past tense switch for `been` 667 | 668 | 0.2.3 / 2012-02-01 669 | ================== 670 | 671 | * try that again 672 | 673 | 0.2.2 / 2012-02-01 674 | ================== 675 | 676 | * added `been` (past of `be`) alias 677 | 678 | 0.2.1 / 2012-01-29 679 | ================== 680 | 681 | * added Throw, with a capital T, as an alias to `throw` (#7) 682 | 683 | 0.2.0 / 2012-01-26 684 | ================== 685 | 686 | * update gitignore for vim *.swp 687 | * Merge branch 'feature/plugins' 688 | * browser build 689 | * interfaces now work with use 690 | * simple .use function. See #9. 691 | * readme notice on browser compat 692 | 693 | 0.1.7 / 2012-01-25 694 | ================== 695 | 696 | * added assert tests to browser test runner 697 | * browser update 698 | * `should` interface patch for primitives support in FF 699 | * fix isObject() Thanks @milewise 700 | * travis only on branch `master` 701 | * add instanceof alias `instanceOf`. #6 702 | * some tests for assert module 703 | 704 | 0.1.6 / 2012-01-02 705 | ================== 706 | 707 | * commenting for assert interface 708 | * updated codex dep 709 | 710 | 0.1.5 / 2012-01-02 711 | ================== 712 | 713 | * browser tests pass 714 | * type in should.not.equal 715 | * test for should (not) exist 716 | * added should.exist and should.not.exist 717 | * browser uses tdd 718 | * convert tests to tdd 719 | 720 | 0.1.4 / 2011-12-26 721 | ================== 722 | 723 | * browser lib update for new assert interface compatiblitiy 724 | * inspect typos 725 | * added strict equal + negatives and ifError 726 | * interface assert had doesNotThrow 727 | * added should tests to browser 728 | * new expect empty tests 729 | * should test browser compat 730 | * Fix typo for instanceof docs. Closes #3 [ci skip] 731 | 732 | 0.1.3 / 2011-12-18 733 | ================== 734 | 735 | * much cleaner reporting string on error. 736 | 737 | 0.1.2 / 2011-12-18 738 | ================== 739 | 740 | * [docs] for upcoming 0.1.2 741 | * browser version built with pre/suffix … all tests passing 742 | * make / compile now use prefix/suffix correctly 743 | * code clean 744 | * prefix/suffix to wrap browser output to prevent conflicts with other `require` methods. 745 | * Merge branch 'feature/should4xcompatibility' 746 | * compile for browser tests.. all pass 747 | * added header/status/html/json 748 | * throw tests 749 | * should.throw & should.not.throw shortcuts 750 | * improved `throw` type detection and messaging 751 | * contain is now `include` … keys modifier is now `contain` 752 | * removed object() test 753 | * removed #respondTo 754 | * Merge branch 'bug/2' 755 | * replaced __defineGetter__ with defineProperty for all uses 756 | * [docs] change mp tracking code 757 | * docs site updated with assert (TDD) interface 758 | * updated doc comments for assert interface 759 | 760 | 0.1.1 / 2011-12-16 761 | ================== 762 | 763 | * docs ready for upcoming 0.1.1 764 | * readme image fixed [ci skip] 765 | * more readme tweaks [ci skip] 766 | * réadmet image fixed [ci skip] 767 | * documentation 768 | * codex locked in version 0.0.5 769 | * more comments to assertions for docs 770 | * assertions fully commented, browser library updated 771 | * adding codex as doc dependancy 772 | * prepping for docs 773 | * assertion component completely commented for documentation 774 | * added exist test 775 | * var expect outside of browser if check 776 | * added keywords to package.json 777 | 778 | 0.1.0 / 2011-12-15 779 | ================== 780 | 781 | * failing on purpose successful .. back to normal 782 | * testing travis failure 783 | * assert#arguments getter 784 | * readme typo 785 | * updated README 786 | * added travis and npmignore 787 | * copyright notices … think i got them all 788 | * moved expect interface to own file for consistency 789 | * assert ui deepEqual 790 | * browser tests expect (all working) 791 | * browser version built 792 | * chai.fail (should ui) 793 | * expect tests browser compatible 794 | * tests for should and expect (all pass) 795 | * moved fail to primary export 796 | * should compatibility testing 797 | * within, greaterThan, object, keys, 798 | * Aliases 799 | * Assertion#property now correctly works with negate and undefined values 800 | * error message language matches should 801 | * Assertion#respondTo 802 | * Assertion now uses inspect util 803 | * git ignore node modules 804 | * should is exported 805 | * AssertionError __proto__ from Error.prototype 806 | * add should interface for should.js compatibility 807 | * moved eql to until folder and added inspect from (joyent/node) 808 | * added mocha for testing 809 | * browser build for current api 810 | * multiple .property assertions 811 | * added deep equal from node 812 | 813 | 0.0.2 / 2011-12-07 814 | ================== 815 | 816 | * cleaner output on error 817 | * improved exists detection 818 | * package remnant artifact 819 | * empty deep equal 820 | * test browser build 821 | * assertion cleanup 822 | * client compile script 823 | * makefile 824 | * most of the basic assertions 825 | * allow no parameters to assertion error 826 | * name change 827 | * assertion error instance 828 | * main exports: assert() & expect() 829 | * initialize 830 | -------------------------------------------------------------------------------- /spec/reports/Test Results - spec_index_ts - 20160816.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Test Results — spec\index.ts 6 | 278 | 279 | 282 | 322 | 556 | 570 | 571 | 572 | 573 |
574 | 590 |
591 |
    592 |
  • 593 | 594 |
    2 ms
    595 |
    index()
    596 |
      597 |
    • 598 | 599 |
      1 ms
      600 |
      passedsimple json object #1
      601 |
    • 602 |
    • 603 | 604 |
      0 ms
      605 |
      passedsimple json object #2
      606 |
    • 607 |
    • 608 | 609 |
      0 ms
      610 |
      passedcomplex json object #1
      611 |
    • 612 |
    • 613 | 614 |
      0 ms
      615 |
      passedempty json object #1
      616 |
    • 617 |
    • 618 | 619 |
      0 ms
      620 |
      passedempty json object #2
      621 |
    • 622 |
    • 623 | 624 |
      0 ms
      625 |
      passedempty json object #3
      626 |
    • 627 |
    • 628 | 629 |
      0 ms
      630 |
      passedinvalid primitive value #1
      631 |
    • 632 |
    • 633 | 634 |
      0 ms
      635 |
      passedinvalid primitive value #2
      636 |
    • 637 |
    • 638 | 639 |
      0 ms
      640 |
      passedinvalid primitive value #3
      641 |
    • 642 |
    • 643 | 644 |
      1 ms
      645 |
      passedinvalid json object #1
      646 |
    • 647 |
    648 |
  • 649 |
650 |
651 |
652 | 655 | 656 | 657 | --------------------------------------------------------------------------------