pax_global_header00006660000000000000000000000064126342251350014515gustar00rootroot0000000000000052 comment=594154be12dd86652accab4cee3d08c448d99093 es5-shim-4.4.1/000077500000000000000000000000001263422513500131555ustar00rootroot00000000000000es5-shim-4.4.1/.eslintrc000066400000000000000000000022451263422513500150040ustar00rootroot00000000000000{ "root": true, "extends": "@ljharb", "rules": { "camelcase": [0], "complexity": [0, 10], "dot-notation": [2, { "allowKeywords": false }], "eqeqeq": [2, "allow-null"], "id-length": [2, { "min": 1, "max": 40 }], "max-nested-callbacks": [2, 5], "max-params": [2, 7], "max-statements": [1, 30], "new-cap": [2, { "capIsNewExceptions": ["ToInteger", "ToObject", "ToPrimitive", "ToUint32"] }], "no-constant-condition": [1], "no-extend-native": [2, {"exceptions": ["Date", "Error", "RegExp"]}], "no-extra-parens": [0], "no-extra-semi": [1], "no-func-assign": [1], "no-implicit-coercion": [2, { "boolean": false, "number": false, "string": true }], "no-invalid-this": [0], "no-magic-numbers": [0], "no-native-reassign": [2, {"exceptions": ["Date", "parseInt"]}], "no-new-func": [1], "no-plusplus": [1], "no-restricted-syntax": [2, "ContinueStatement", "DebuggerStatement", "LabeledStatement", "WithStatement"], "no-shadow": [1], "no-unused-vars": [1, { "vars": "all", "args": "after-used" }], "operator-linebreak": [2, "after"], "quote-props": [1, "as-needed", { "keywords": true }], "spaced-comment": [0], "strict": [0] } } es5-shim-4.4.1/.gitignore000066400000000000000000000000271263422513500151440ustar00rootroot00000000000000node_modules .DS_Store es5-shim-4.4.1/.jscs.json000066400000000000000000000066521263422513500151010ustar00rootroot00000000000000{ "es3": true, "additionalRules": [], "requireSemicolons": true, "disallowMultipleSpaces": true, "disallowIdentifierNames": [], "requireCurlyBraces": { "allExcept": [], "keywords": ["if", "else", "for", "while", "do", "try", "catch"] }, "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"], "disallowSpaceAfterKeywords": [], "disallowSpaceBeforeComma": true, "disallowSpaceAfterComma": false, "disallowSpaceBeforeSemicolon": true, "disallowNodeTypes": [ "DebuggerStatement", "LabeledStatement", "SwitchCase", "SwitchStatement", "WithStatement" ], "requireObjectKeysOnNewLine": { "allExcept": ["sameLine"] }, "requireSpacesInAnonymousFunctionExpression": { "beforeOpeningRoundBrace": true, "beforeOpeningCurlyBrace": true }, "requireSpacesInNamedFunctionExpression": { "beforeOpeningCurlyBrace": true }, "disallowSpacesInNamedFunctionExpression": { "beforeOpeningRoundBrace": true }, "requireSpacesInFunctionDeclaration": { "beforeOpeningCurlyBrace": true }, "disallowSpacesInFunctionDeclaration": { "beforeOpeningRoundBrace": true }, "requireSpaceBetweenArguments": true, "disallowSpacesInsideParentheses": true, "disallowSpacesInsideArrayBrackets": true, "disallowQuotedKeysInObjects": "allButReserved", "disallowSpaceAfterObjectKeys": true, "requireCommaBeforeLineBreak": true, "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], "requireSpaceAfterPrefixUnaryOperators": [], "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], "requireSpaceBeforePostfixUnaryOperators": [], "disallowSpaceBeforeBinaryOperators": [], "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], "disallowSpaceAfterBinaryOperators": [], "disallowImplicitTypeConversion": ["binary", "string"], "disallowKeywords": ["with", "eval"], "requireKeywordsOnNewLine": [], "disallowKeywordsOnNewLine": ["else"], "requireLineFeedAtFileEnd": true, "disallowTrailingWhitespace": true, "disallowTrailingComma": true, "excludeFiles": ["node_modules/**", "vendor/**"], "disallowMultipleLineStrings": true, "requireDotNotation": { "allExcept": ["keywords"] }, "requireParenthesesAroundIIFE": true, "validateLineBreaks": "LF", "validateQuoteMarks": { "escape": true, "mark": "'" }, "disallowOperatorBeforeLineBreak": [], "requireSpaceBeforeKeywords": [ "do", "for", "if", "else", "switch", "case", "try", "catch", "finally", "while", "with", "return" ], "validateAlignedFunctionParameters": { "lineBreakAfterOpeningBraces": true, "lineBreakBeforeClosingBraces": true }, "requirePaddingNewLinesBeforeExport": true, "validateNewlineAfterArrayElements": { "maximum": 200 }, "requirePaddingNewLinesAfterUseStrict": true, "disallowArrowFunctions": true, "disallowMultiLineTernary": false, "validateOrderInObjectKeys": false, "disallowIdenticalDestructuringNames": true, "disallowNestedTernaries": { "maxLevel": 7 }, "requireSpaceAfterComma": { "allExcept": ["trailing"] }, "requireAlignedMultilineParams": false, "requireSpacesInGenerator": { "afterStar": true }, "disallowSpacesInGenerator": { "beforeStar": true }, "disallowVar": false, "requireArrayDestructuring": false, "requireEnhancedObjectLiterals": false, "requireObjectDestructuring": false } es5-shim-4.4.1/.travis.yml000066400000000000000000000027071263422513500152740ustar00rootroot00000000000000language: node_js node_js: - "5.1" - "5.0" - "4.2" - "4.1" - "4.0" - "iojs-v3.3" - "iojs-v3.2" - "iojs-v3.1" - "iojs-v3.0" - "iojs-v2.5" - "iojs-v2.4" - "iojs-v2.3" - "iojs-v2.2" - "iojs-v2.1" - "iojs-v2.0" - "iojs-v1.8" - "iojs-v1.7" - "iojs-v1.6" - "iojs-v1.5" - "iojs-v1.4" - "iojs-v1.3" - "iojs-v1.2" - "iojs-v1.1" - "iojs-v1.0" - "0.12" - "0.11" - "0.10" - "0.9" - "0.8" - "0.6" - "0.4" before_install: - 'if [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then case "$(npm --version)" in 1.*) npm install -g npm@1.4.28 ;; 2.*) npm install -g npm@2 ;; esac ; fi' - 'if [ "${TRAVIS_NODE_VERSION}" != "0.6" ] && [ "${TRAVIS_NODE_VERSION}" != "0.9" ]; then npm install -g npm; fi' script: - 'if [ "${TRAVIS_NODE_VERSION}" != "4.2" ]; then npm run tests-only ; else npm test ; fi' sudo: false matrix: fast_finish: true allow_failures: - node_js: "5.0" - node_js: "4.1" - node_js: "4.0" - node_js: "iojs-v3.2" - node_js: "iojs-v3.1" - node_js: "iojs-v3.0" - node_js: "iojs-v2.4" - node_js: "iojs-v2.3" - node_js: "iojs-v2.2" - node_js: "iojs-v2.1" - node_js: "iojs-v2.0" - node_js: "iojs-v1.7" - node_js: "iojs-v1.6" - node_js: "iojs-v1.5" - node_js: "iojs-v1.4" - node_js: "iojs-v1.3" - node_js: "iojs-v1.2" - node_js: "iojs-v1.1" - node_js: "iojs-v1.0" - node_js: "0.11" - node_js: "0.9" - node_js: "0.6" - node_js: "0.4" es5-shim-4.4.1/CHANGES000066400000000000000000000337751263422513500141670ustar00rootroot000000000000004.4.1 - [Fix] ensure that IE 11 in compatibility mode doesn't throw (#370) - [Docs] add missing shimmed things 4.4.0 - [New] Detect and patch `RegExp#toString` in IE 8, which returns flags in the wrong order (#364) - [Fix] Patch `Array#sort` on {Chrome, Safari, IE < 9, FF 4} that throws improperly, per ES5 (#354) - [Fix] In IE 6, `window.external` makes `Object.keys` throw - [Fix] `Array#slice`: boxed string access on IE <= 8 (#349) - [Fix] `Array#join`: fix IE 6-8 join called on string literal (#352) - [Fix] Ensure that `Error#message` and `Error#name` are non-enumerable (#358) - [Fix: sham] `Object.getOwnPropertyDescriptor`: In Opera 11.6, `propertyIsEnumerable` is a nonshadowable global, like `toString` - [Robustness] Use a bound form of `Array#slice.call` - [Tests] Properly check for descriptor support in IE <= 8 - [Tests] on `node` `v5.1` - [Tests] Add `Array#slice` tests (#346) - [Dev Deps] update `uglify-js`, `eslint`, `jscs`, `uglify-js`, `semver` - [Docs] Fix broken UMD links (#344) 4.3.1 - [Fix] `String#split`: revert part of dcce96ae21185a69d2d40e67416e7496b73e8e47 which broke in older browsers (#342) - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs` - [Tests] Firefox allows `Number#toPrecision` values of [1,100], which the spec permits 4.3.0 - [New] `Array#push`: in IE <= 7, `Array#push` was not generic (#336) - [New] `Array#push` in Opera `10.6` has a super weird bug when pushing `undefined` - [New] `Array#join`: In IE <= 7, passing `undefined` didn't use the default separator (#333) - [New] `Error#toString`: prints out the proper message in IE 7 and below (#334) - [New] `Number#toPrecision`: IE 7 and below incorrectly throw when an explicit `undefined` precision is passed (#340) - [Fix] `String#lastIndexOf`: ensure the correct length in IE 8 - [Fix] ensure `parseInt` accepts negative and plus-prefixed hex values (#332) - [Robustness] Use a bound `Array#push` instead of relying on `Function#call` - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs` - [Tests] Add some conditionals to avoid impossible-to-fix test failures in IE 6-8, due to it being unable to distinguish between `undefined` and an absent index (#114) - [Tests] Fix false negatives in IE 6-8 with jasmine comparing arrays to arraylikes (#114) - [Tests] add additional `Array#shift` tests (#337) - [Tests] Add additional `Array#splice` tests (#339) - [Tests] Add `Array#pop` tests, just in case (#338) - [Tests] include `global` tests in HTML test files - [Tests] Make sure the HTML tests run with the right charset - [Tests] ensure `node` `v0.8` tests stay passing. - [Tests] Prevent nondeterminism in the tests - this sometime produced values that are one ms off - [Tests] on `node` `v5.0` - [Tests] fix npm upgrades for older nodes 4.2.0 - [shim: new] Overwrite `String#lastIndexOf` in IE 9, 10, 11, and Edge, so it has proper unicode support. - [Dev Deps] update `eslint`, `jscs` 4.1.15 - [shim: fix] new Date + Date.parse: Fix a Safari 8 & 9 bug where the `ms` arg is treated as a signed instead of unsigned int (#329) - [shim: fix] add 'frame' to blacklisted keys (#330) - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `jscs`, `uglify-js` - [Tests] on `node` `v4.2` - [Tests] Date: prevent nondeterminism in the tests - this sometime produced values that are one ms off 4.1.14 - [shim: fix] Wrap more things in a try/catch, because IE sucks and sometimes throws on [[Get]] of window.localStorage (#327) - [Refactor] Use `ES.ToUint32` instead of inline `>>>` - [Tests] up to `node` `v4.1` - [Dev Deps] update `eslint`, `@ljharb/eslint-config`, `semver`, `jscs` 4.1.13 - [shim: fix] Fix a bug where `Date(x)` threw instead of equalling `String(Date(x))` (#326) 4.1.12 - [fix] Make sure uglify doesn't remove function names - [shim: fix] Use `is-arguments` implementation; don't call down legacy code path in modern engines (#325) - [Tests] up to `io.js` `v3.3` - [Dev Deps] update `eslint`, `@ljharb/eslint-config` 4.1.11 - [shim: fix] Object.keys in Safari 9 has some bugs. (Already fixed in Webkit Nightly) - [shim: fix] Omit !Date.parse check in the if statement (#323) - [sham: fix] Fix Object.create sham to not set __proto__ (#301) - [sham: fix] Add a typeof check to Object.getPrototypeOf (#319, #320) - [Tests] up to `io.js` `v3.1` - [Tests] Make sure `Object.getPrototypeOf` tests don't fail when engines implement ES6 semantics - [Docs] Switch from vb.teelaun.ch to versionbadg.es for the npm version badge SVG (#318) - [Dev Deps] Update `eslint`, `uglify-js`, `jscs`; use my personal shared `eslint` config 4.1.10 - [Fix] Fix IE 8 issue with `window.frameElement` access in a child iframe (#322) - [Tests] Consolidating `Date.parse` extended year tests - [Tests] Account for a `Date.parse` precision variance in Safari 8 - [Tests] DRY up some Date.parse tests - [Tests] Don't create globals in Date tests - [Tests] Better failure output when an invalid date's toJSON throws - [Tests] Also compare lengths of array-likes - [Tests] Extra check on Object.keys(arguments) - [Tests] Skip appropriate tests when objects aren't extensible/freezeable/sealable 4.1.9 - [Fix] Remove "extended", add "unicode" in `String#split` shim, to match ES6 - [Fix] Object.keys: Preserve the IE 8 dontEnum bugfix, and the automation equality bugfix. - [Fix] Object.keys: Prevent a deprecation message from showing up in Chrome. - [Performance] Speed up blacklisted key check for Object.keys automation equality bug. - [Tests] Test on `io.js` `v2.4` - [Dev Deps] Update `eslint`, `semver` 4.1.8 - [Fix] Fix an `Object.keys` IE 8 bug where `localStorage.prototype.constructor === localStorage` would throw (#275) - [Fix] Shimmed `Object.defineProperty` should not throw for an empty descriptor (#315) - [Fix] Fix `Date#toISOString` in Safari 5.1 (#243) - [Fix] Use `Object#propertyIsEnumerable` to default the initial "enumerable" value in `Object.getOwnPropertyDescriptor` sham (#289) - [Fix] Fix `Array#splice` with large sparse arrays in Safari 7/8, and Opera 12.15 (#295) - [Robustness] Safely use and reference many builtins internally (also see #313) - [Tests] Add `Date#{getUTCDate,getUTCMonth}` tests to expose Opera 10.6/11.61/12 `Date` bugs - [Dev Deps] Update `eslint` 4.1.7 - Make sure `Date.parse` is not enumerable (#310) 4.1.6 - Support IE 8 when `document.domain` is set (#306, #150) - Remove version from `bower.json` (#307) 4.1.5 - Add a failing runtime check for Safari 8 `Date.parse` - Update `eslint`, `semver` - Test on `io.js` `v2.2` 4.1.4 - Make sure copied `Date` properties remain non-enumerable. - Using a more reliable check for supported property descriptors in non-IE ES3 - Fix 'constructor' in Object.defineProperties sham in ES3 (#252, #305) - Use a reference to `Array#concat` rather than relying on the runtime environment's `concat`. - Test on `io.js` `v2.1` - Clean up `Array.prototype` iteration methods 4.1.3 - Update `license` in `package.json` per https://docs.npmjs.com/files/package.json#license - Update `uglify-js`, `eslint` 4.1.2 - In IE 6-8, `Date` inside the function expression does not reference `DateShim` (#303) - Date: Ensure all code paths have the correct `constructor` property - Date: Don't copy non-own properties from original `Date` - Test up to `io.js` `v2.0.0` - Simplify `isPrimitive` check. - Adding sanity check tests for ES5 `Number` constants. - Update `uglify-js`, `eslint`, `semver` 4.1.1 - Fix name of `parseInt` replacement. - Update copyright year - Update `eslint`, `jscs` - Lock `uglify-js` down to v2.4.17, since v2.4.18 and v2.4.19 have a breaking change. - All grade A-supported `node`/`iojs` versions now ship with an `npm` that understands `^`. - Run `travis-ci` tests on latest `node` and `iojs`; speed up builds; allow 0.8 failures. - Ensure some Object tests don't fail in ES6 - Make sure `Date` instances don't have an enumerable `constructor` property, when possible. 4.1.0 - Update `eslint` - Improve type checks: `Array.isArray`, `isRegex` - Replace `isRegex`/`isString`/`isCallable` checks with inlined versions from npm modules - Note which ES abstract methods are replaceable via `es-abstract` - Run `travis-ci` tests on `iojs`! 4.0.6 - Update `jscs`, `uglify-js`, add `eslint` - es5-sham: fix Object.defineProperty to not check for own properties (#211) - Fix Array#splice bug in Safari 5 (#284) - Fix `Object.keys` issue with boxed primitives with extra properties in older browsers. (#242, #285) 4.0.5 - Update `jscs` so tests pass 4.0.4 - Style/indentation/whitespace cleanups. - README tweaks 4.0.3 - Fix keywords (#268) - add some Date tests - Note in README that the es5-sham requires the es5-shim (https://github.com/es-shims/es5-shim/issues/256#issuecomment-52875710) 4.0.2 - Start including version numbers in minified files (#267) 4.0.1 - Fix legacy arguments object detection in Object.keys (#260) 4.0.0 - No longer shim the ES5-spec behavior of splice when `deleteCount` is omitted - since no engines implement it, and ES6 changes it. (#255) - Use Object.defineProperty where available, so that polyfills are non-enumerable when possible (#250) - lots of internal refactoring - Fixed a bug referencing String#indexOf and String#lastIndexOf before polyfilling it (#253, #254) 3.4.0 - Removed nonstandard SpiderMonkey extension to Array#splice - when `deleteCount` is omitted, it's now treated as 0. (#192, #239) - Fix Object.keys with Arguments objects in Safari 5.0 - Now shimming String#split in Opera 10.6 - Avoid using "toString" as a variable name, since that breaks Opera - Internal implementation and test cleanups 3.3.2 - Remove an internal "bind" call, which should make the shim a bit faster - Fix a bug with object boxing in Array#reduceRight that was failing a test in IE 6 3.3.1 - Fixing an Array#splice bug in IE 6/7 - cleaning up Array#splice tests 3.3.0 - Fix Array#reduceRight in node 0.6 and older browsers (#238) 3.2.0 - Fix es5-sham UMD definition to work properly with AMD (#237) - Ensure that Array methods do not autobox context in strict mode (#233) 3.1.1 - Update minified files (#231) 3.1.0 - Fix String#replace in Firefox up through 29 (#228) 3.0.2 - Fix `Function#bind` in IE 7 and 8 (#224, #225, #226) 3.0.1 - Version bump to ensure npm has newest minified assets 3.0.0 - es5-sham: fix `Object.getPrototypeOf` and `Object.getOwnPropertyDescriptor` for Opera Mini - Better override noncompliant native ES5 methods: `Array#forEach`, `Array#map`, `Array#filter`, `Array#every`, `Array#some`, `Array#reduce`, `Date.parse`, `String#trim` - Added spec-compliant shim for `parseInt` - Ensure `Object.keys` handles more edge cases with `arguments` objects and boxed primitives - Improve minification of builds 2.3.0 - parseInt is now properly shimmed in ES3 browsers to default the radix - update URLs to point to the new organization 2.2.0 - Function.prototype.bind shim now reports correct length on a bound function - fix node 0.6.x v8 bug in Array#forEach - test improvements 2.1.0 - Object.create fixes - tweaks to the Object.defineProperties shim 2.0.0 - Separate reliable shims from dubious shims (shams). 1.2.10 - Group-effort Style Cleanup - Took a stab at fixing Object.defineProperty on IE8 without bad side-effects. (@hax) - Object.isExtensible no longer fakes it. (@xavierm) - Date.prototype.toISOString no longer deals with partial ISO dates, per spec (@kitcambridge) - More (mostly from @bryanforbes) 1.2.9 - Corrections to toISOString by @kitcambridge - Fixed three bugs in array methods revealed by Jasmine tests. - Cleaned up Function.prototype.bind with more fixes and tests from @bryanforbes. 1.2.8 - Actually fixed problems with Function.prototype.bind, and regressions from 1.2.7 (@bryanforbes, @jdalton #36) 1.2.7 - REGRESSED - Fixed problems with Function.prototype.bind when called as a constructor. (@jdalton #36) 1.2.6 - Revised Date.parse to match ES 5.1 (kitcambridge) 1.2.5 - Fixed a bug for padding it Date..toISOString (tadfisher issue #33) 1.2.4 - Fixed a descriptor bug in Object.defineProperty (raynos) 1.2.3 - Cleaned up RequireJS and ");t.close();e=t.parentWindow.Object.prototype;t=null;return e};var _=function getEmptyViaIFrame(){var e=document.createElement("iframe");var t=document.body||document.documentElement;var r;e.style.display="none";t.appendChild(e);e.src="javascript:";r=e.contentWindow.Object.prototype;t.removeChild(e);e=null;return r};if(d||typeof document==="undefined"){y=function(){return{__proto__:null}}}else{y=function(){var e=j()?v():_();delete e.constructor;delete e.hasOwnProperty;delete e.propertyIsEnumerable;delete e.isPrototypeOf;delete e.toLocaleString;delete e.toString;delete e.valueOf;var t=function Empty(){};t.prototype=e;y=function(){return new t};return new t}}Object.create=function create(e,t){var r;var n=function Type(){};if(e===null){r=y()}else{if(typeof e!=="object"&&typeof e!=="function"){throw new TypeError("Object prototype may only be an Object or null")}n.prototype=e;r=new n;r.__proto__=e}if(t!==void 0){Object.defineProperties(r,t)}return r}}var w=function doesDefinePropertyWork(e){try{Object.defineProperty(e,"sentinel",{});return"sentinel"in e}catch(t){return false}};if(Object.defineProperty){var m=w({});var P=typeof document==="undefined"||w(document.createElement("div"));if(!m||!P){var E=Object.defineProperty,h=Object.defineProperties}}if(!Object.defineProperty||E){var g="Property description must be an object: ";var z="Object.defineProperty called on non-object: ";var T="getters & setters can not be defined on this javascript engine";Object.defineProperty=function defineProperty(e,r,n){if(typeof e!=="object"&&typeof e!=="function"||e===null){throw new TypeError(z+e)}if(typeof n!=="object"&&typeof n!=="function"||n===null){throw new TypeError(g+n)}if(E){try{return E.call(Object,e,r,n)}catch(o){}}if("value"in n){if(l&&(f(e,r)||a(e,r))){var u=e.__proto__;e.__proto__=t;delete e[r];e[r]=n.value;e.__proto__=u}else{e[r]=n.value}}else{if(!l&&("get"in n||"set"in n)){throw new TypeError(T)}if("get"in n){i(e,r,n.get)}if("set"in n){c(e,r,n.set)}}return e}}if(!Object.defineProperties||h){Object.defineProperties=function defineProperties(e,t){if(h){try{return h.call(Object,e,t)}catch(r){}}Object.keys(t).forEach(function(r){if(r!=="__proto__"){Object.defineProperty(e,r,t[r])}});return e}}if(!Object.seal){Object.seal=function seal(e){if(Object(e)!==e){throw new TypeError("Object.seal can only be called on Objects.")}return e}}if(!Object.freeze){Object.freeze=function freeze(e){if(Object(e)!==e){throw new TypeError("Object.freeze can only be called on Objects.")}return e}}try{Object.freeze(function(){})}catch(x){Object.freeze=function(e){return function freeze(t){if(typeof t==="function"){return t}else{return e(t)}}}(Object.freeze)}if(!Object.preventExtensions){Object.preventExtensions=function preventExtensions(e){if(Object(e)!==e){throw new TypeError("Object.preventExtensions can only be called on Objects.")}return e}}if(!Object.isSealed){Object.isSealed=function isSealed(e){if(Object(e)!==e){throw new TypeError("Object.isSealed can only be called on Objects.")}return false}}if(!Object.isFrozen){Object.isFrozen=function isFrozen(e){if(Object(e)!==e){throw new TypeError("Object.isFrozen can only be called on Objects.")}return false}}if(!Object.isExtensible){Object.isExtensible=function isExtensible(e){if(Object(e)!==e){throw new TypeError("Object.isExtensible can only be called on Objects.")}var t="";while(r(e,t)){t+="?"}e[t]=true;var n=r(e,t);delete e[t];return n}}}); //# sourceMappingURL=es5-sham.map es5-shim-4.4.1/es5-shim.js000066400000000000000000002036761263422513500151630ustar00rootroot00000000000000/*! * https://github.com/es-shims/es5-shim * @license es5-shim Copyright 2009-2015 by contributors, MIT License * see https://github.com/es-shims/es5-shim/blob/master/LICENSE */ // vim: ts=4 sts=4 sw=4 expandtab // Add semicolon to prevent IIFE from being passed as argument to concatenated code. ; // UMD (Universal Module Definition) // see https://github.com/umdjs/umd/blob/master/templates/returnExports.js (function (root, factory) { 'use strict'; /* global define, exports, module */ if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(factory); } else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like enviroments that support module.exports, // like Node. module.exports = factory(); } else { // Browser globals (root is window) root.returnExports = factory(); } }(this, function () { /** * Brings an environment as close to ECMAScript 5 compliance * as is possible with the facilities of erstwhile engines. * * Annotated ES5: http://es5.github.com/ (specific links below) * ES5 Spec: http://www.ecma-international.org/publications/files/ECMA-ST/Ecma-262.pdf * Required reading: http://javascriptweblog.wordpress.com/2011/12/05/extending-javascript-natives/ */ // Shortcut to an often accessed properties, in order to avoid multiple // dereference that costs universally. This also holds a reference to known-good // functions. var $Array = Array; var ArrayPrototype = $Array.prototype; var $Object = Object; var ObjectPrototype = $Object.prototype; var FunctionPrototype = Function.prototype; var $String = String; var StringPrototype = $String.prototype; var $Number = Number; var NumberPrototype = $Number.prototype; var array_slice = ArrayPrototype.slice; var array_splice = ArrayPrototype.splice; var array_push = ArrayPrototype.push; var array_unshift = ArrayPrototype.unshift; var array_concat = ArrayPrototype.concat; var call = FunctionPrototype.call; var apply = FunctionPrototype.apply; var max = Math.max; var min = Math.min; // Having a toString local variable name breaks in Opera so use to_string. var to_string = ObjectPrototype.toString; var hasToStringTag = typeof Symbol === 'function' && typeof Symbol.toStringTag === 'symbol'; var isCallable; /* inlined from https://npmjs.com/is-callable */ var fnToStr = Function.prototype.toString, tryFunctionObject = function tryFunctionObject(value) { try { fnToStr.call(value); return true; } catch (e) { return false; } }, fnClass = '[object Function]', genClass = '[object GeneratorFunction]'; isCallable = function isCallable(value) { if (typeof value !== 'function') { return false; } if (hasToStringTag) { return tryFunctionObject(value); } var strClass = to_string.call(value); return strClass === fnClass || strClass === genClass; }; var isRegex; /* inlined from https://npmjs.com/is-regex */ var regexExec = RegExp.prototype.exec, tryRegexExec = function tryRegexExec(value) { try { regexExec.call(value); return true; } catch (e) { return false; } }, regexClass = '[object RegExp]'; isRegex = function isRegex(value) { if (typeof value !== 'object') { return false; } return hasToStringTag ? tryRegexExec(value) : to_string.call(value) === regexClass; }; var isString; /* inlined from https://npmjs.com/is-string */ var strValue = String.prototype.valueOf, tryStringObject = function tryStringObject(value) { try { strValue.call(value); return true; } catch (e) { return false; } }, stringClass = '[object String]'; isString = function isString(value) { if (typeof value === 'string') { return true; } if (typeof value !== 'object') { return false; } return hasToStringTag ? tryStringObject(value) : to_string.call(value) === stringClass; }; /* inlined from http://npmjs.com/define-properties */ var supportsDescriptors = $Object.defineProperty && (function () { try { var obj = {}; $Object.defineProperty(obj, 'x', { enumerable: false, value: obj }); for (var _ in obj) { return false; } return obj.x === obj; } catch (e) { /* this is ES3 */ return false; } }()); var defineProperties = (function (has) { // Define configurable, writable, and non-enumerable props // if they don't exist. var defineProperty; if (supportsDescriptors) { defineProperty = function (object, name, method, forceAssign) { if (!forceAssign && (name in object)) { return; } $Object.defineProperty(object, name, { configurable: true, enumerable: false, writable: true, value: method }); }; } else { defineProperty = function (object, name, method, forceAssign) { if (!forceAssign && (name in object)) { return; } object[name] = method; }; } return function defineProperties(object, map, forceAssign) { for (var name in map) { if (has.call(map, name)) { defineProperty(object, name, map[name], forceAssign); } } }; }(ObjectPrototype.hasOwnProperty)); // // Util // ====== // /* replaceable with https://npmjs.com/package/es-abstract /helpers/isPrimitive */ var isPrimitive = function isPrimitive(input) { var type = typeof input; return input === null || (type !== 'object' && type !== 'function'); }; var isActualNaN = $Number.isNaN || function (x) { return x !== x; }; var ES = { // ES5 9.4 // http://es5.github.com/#x9.4 // http://jsperf.com/to-integer /* replaceable with https://npmjs.com/package/es-abstract ES5.ToInteger */ ToInteger: function ToInteger(num) { var n = +num; if (isActualNaN(n)) { n = 0; } else if (n !== 0 && n !== (1 / 0) && n !== -(1 / 0)) { n = (n > 0 || -1) * Math.floor(Math.abs(n)); } return n; }, /* replaceable with https://npmjs.com/package/es-abstract ES5.ToPrimitive */ ToPrimitive: function ToPrimitive(input) { var val, valueOf, toStr; if (isPrimitive(input)) { return input; } valueOf = input.valueOf; if (isCallable(valueOf)) { val = valueOf.call(input); if (isPrimitive(val)) { return val; } } toStr = input.toString; if (isCallable(toStr)) { val = toStr.call(input); if (isPrimitive(val)) { return val; } } throw new TypeError(); }, // ES5 9.9 // http://es5.github.com/#x9.9 /* replaceable with https://npmjs.com/package/es-abstract ES5.ToObject */ ToObject: function (o) { if (o == null) { // this matches both null and undefined throw new TypeError("can't convert " + o + ' to object'); } return $Object(o); }, /* replaceable with https://npmjs.com/package/es-abstract ES5.ToUint32 */ ToUint32: function ToUint32(x) { return x >>> 0; } }; // // Function // ======== // // ES-5 15.3.4.5 // http://es5.github.com/#x15.3.4.5 var Empty = function Empty() {}; defineProperties(FunctionPrototype, { bind: function bind(that) { // .length is 1 // 1. Let Target be the this value. var target = this; // 2. If IsCallable(Target) is false, throw a TypeError exception. if (!isCallable(target)) { throw new TypeError('Function.prototype.bind called on incompatible ' + target); } // 3. Let A be a new (possibly empty) internal list of all of the // argument values provided after thisArg (arg1, arg2 etc), in order. // XXX slicedArgs will stand in for "A" if used var args = array_slice.call(arguments, 1); // for normal call // 4. Let F be a new native ECMAScript object. // 11. Set the [[Prototype]] internal property of F to the standard // built-in Function prototype object as specified in 15.3.3.1. // 12. Set the [[Call]] internal property of F as described in // 15.3.4.5.1. // 13. Set the [[Construct]] internal property of F as described in // 15.3.4.5.2. // 14. Set the [[HasInstance]] internal property of F as described in // 15.3.4.5.3. var bound; var binder = function () { if (this instanceof bound) { // 15.3.4.5.2 [[Construct]] // When the [[Construct]] internal method of a function object, // F that was created using the bind function is called with a // list of arguments ExtraArgs, the following steps are taken: // 1. Let target be the value of F's [[TargetFunction]] // internal property. // 2. If target has no [[Construct]] internal method, a // TypeError exception is thrown. // 3. Let boundArgs be the value of F's [[BoundArgs]] internal // property. // 4. Let args be a new list containing the same values as the // list boundArgs in the same order followed by the same // values as the list ExtraArgs in the same order. // 5. Return the result of calling the [[Construct]] internal // method of target providing args as the arguments. var result = target.apply( this, array_concat.call(args, array_slice.call(arguments)) ); if ($Object(result) === result) { return result; } return this; } else { // 15.3.4.5.1 [[Call]] // When the [[Call]] internal method of a function object, F, // which was created using the bind function is called with a // this value and a list of arguments ExtraArgs, the following // steps are taken: // 1. Let boundArgs be the value of F's [[BoundArgs]] internal // property. // 2. Let boundThis be the value of F's [[BoundThis]] internal // property. // 3. Let target be the value of F's [[TargetFunction]] internal // property. // 4. Let args be a new list containing the same values as the // list boundArgs in the same order followed by the same // values as the list ExtraArgs in the same order. // 5. Return the result of calling the [[Call]] internal method // of target providing boundThis as the this value and // providing args as the arguments. // equiv: target.call(this, ...boundArgs, ...args) return target.apply( that, array_concat.call(args, array_slice.call(arguments)) ); } }; // 15. If the [[Class]] internal property of Target is "Function", then // a. Let L be the length property of Target minus the length of A. // b. Set the length own property of F to either 0 or L, whichever is // larger. // 16. Else set the length own property of F to 0. var boundLength = max(0, target.length - args.length); // 17. Set the attributes of the length own property of F to the values // specified in 15.3.5.1. var boundArgs = []; for (var i = 0; i < boundLength; i++) { array_push.call(boundArgs, '$' + i); } // XXX Build a dynamic function with desired amount of arguments is the only // way to set the length property of a function. // In environments where Content Security Policies enabled (Chrome extensions, // for ex.) all use of eval or Function costructor throws an exception. // However in all of these environments Function.prototype.bind exists // and so this code will never be executed. bound = Function('binder', 'return function (' + boundArgs.join(',') + '){ return binder.apply(this, arguments); }')(binder); if (target.prototype) { Empty.prototype = target.prototype; bound.prototype = new Empty(); // Clean up dangling references. Empty.prototype = null; } // TODO // 18. Set the [[Extensible]] internal property of F to true. // TODO // 19. Let thrower be the [[ThrowTypeError]] function Object (13.2.3). // 20. Call the [[DefineOwnProperty]] internal method of F with // arguments "caller", PropertyDescriptor {[[Get]]: thrower, [[Set]]: // thrower, [[Enumerable]]: false, [[Configurable]]: false}, and // false. // 21. Call the [[DefineOwnProperty]] internal method of F with // arguments "arguments", PropertyDescriptor {[[Get]]: thrower, // [[Set]]: thrower, [[Enumerable]]: false, [[Configurable]]: false}, // and false. // TODO // NOTE Function objects created using Function.prototype.bind do not // have a prototype property or the [[Code]], [[FormalParameters]], and // [[Scope]] internal properties. // XXX can't delete prototype in pure-js. // 22. Return F. return bound; } }); // _Please note: Shortcuts are defined after `Function.prototype.bind` as we // use it in defining shortcuts. var owns = call.bind(ObjectPrototype.hasOwnProperty); var toStr = call.bind(ObjectPrototype.toString); var arraySlice = call.bind(array_slice); var arraySliceApply = apply.bind(array_slice); var strSlice = call.bind(StringPrototype.slice); var strSplit = call.bind(StringPrototype.split); var strIndexOf = call.bind(StringPrototype.indexOf); var push = call.bind(array_push); var isEnum = call.bind(ObjectPrototype.propertyIsEnumerable); var arraySort = call.bind(ArrayPrototype.sort); // // Array // ===== // var isArray = $Array.isArray || function isArray(obj) { return toStr(obj) === '[object Array]'; }; // ES5 15.4.4.12 // http://es5.github.com/#x15.4.4.13 // Return len+argCount. // [bugfix, ielt8] // IE < 8 bug: [].unshift(0) === undefined but should be "1" var hasUnshiftReturnValueBug = [].unshift(0) !== 1; defineProperties(ArrayPrototype, { unshift: function () { array_unshift.apply(this, arguments); return this.length; } }, hasUnshiftReturnValueBug); // ES5 15.4.3.2 // http://es5.github.com/#x15.4.3.2 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray defineProperties($Array, { isArray: isArray }); // The IsCallable() check in the Array functions // has been replaced with a strict check on the // internal class of the object to trap cases where // the provided function was actually a regular // expression literal, which in V8 and // JavaScriptCore is a typeof "function". Only in // V8 are regular expression literals permitted as // reduce parameters, so it is desirable in the // general case for the shim to match the more // strict and common behavior of rejecting regular // expressions. // ES5 15.4.4.18 // http://es5.github.com/#x15.4.4.18 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/array/forEach // Check failure of by-index access of string characters (IE < 9) // and failure of `0 in boxedString` (Rhino) var boxedString = $Object('a'); var splitString = boxedString[0] !== 'a' || !(0 in boxedString); var properlyBoxesContext = function properlyBoxed(method) { // Check node 0.6.21 bug where third parameter is not boxed var properlyBoxesNonStrict = true; var properlyBoxesStrict = true; if (method) { method.call('foo', function (_, __, context) { if (typeof context !== 'object') { properlyBoxesNonStrict = false; } }); method.call([1], function () { 'use strict'; properlyBoxesStrict = typeof this === 'string'; }, 'x'); } return !!method && properlyBoxesNonStrict && properlyBoxesStrict; }; defineProperties(ArrayPrototype, { forEach: function forEach(callbackfn/*, thisArg*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var i = -1; var length = ES.ToUint32(self.length); var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.forEach callback must be a function'); } while (++i < length) { if (i in self) { // Invoke the callback function with call, passing arguments: // context, property value, property key, thisArg object if (typeof T === 'undefined') { callbackfn(self[i], i, object); } else { callbackfn.call(T, self[i], i, object); } } } } }, !properlyBoxesContext(ArrayPrototype.forEach)); // ES5 15.4.4.19 // http://es5.github.com/#x15.4.4.19 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/map defineProperties(ArrayPrototype, { map: function map(callbackfn/*, thisArg*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); var result = $Array(length); var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.map callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self) { if (typeof T === 'undefined') { result[i] = callbackfn(self[i], i, object); } else { result[i] = callbackfn.call(T, self[i], i, object); } } } return result; } }, !properlyBoxesContext(ArrayPrototype.map)); // ES5 15.4.4.20 // http://es5.github.com/#x15.4.4.20 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/filter defineProperties(ArrayPrototype, { filter: function filter(callbackfn/*, thisArg*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); var result = []; var value; var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.filter callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self) { value = self[i]; if (typeof T === 'undefined' ? callbackfn(value, i, object) : callbackfn.call(T, value, i, object)) { push(result, value); } } } return result; } }, !properlyBoxesContext(ArrayPrototype.filter)); // ES5 15.4.4.16 // http://es5.github.com/#x15.4.4.16 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every defineProperties(ArrayPrototype, { every: function every(callbackfn/*, thisArg*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.every callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self && !(typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) { return false; } } return true; } }, !properlyBoxesContext(ArrayPrototype.every)); // ES5 15.4.4.17 // http://es5.github.com/#x15.4.4.17 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some defineProperties(ArrayPrototype, { some: function some(callbackfn/*, thisArg */) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); var T; if (arguments.length > 1) { T = arguments[1]; } // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.some callback must be a function'); } for (var i = 0; i < length; i++) { if (i in self && (typeof T === 'undefined' ? callbackfn(self[i], i, object) : callbackfn.call(T, self[i], i, object))) { return true; } } return false; } }, !properlyBoxesContext(ArrayPrototype.some)); // ES5 15.4.4.21 // http://es5.github.com/#x15.4.4.21 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduce var reduceCoercesToObject = false; if (ArrayPrototype.reduce) { reduceCoercesToObject = typeof ArrayPrototype.reduce.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } defineProperties(ArrayPrototype, { reduce: function reduce(callbackfn/*, initialValue*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.reduce callback must be a function'); } // no value to return if no initial value and an empty array if (length === 0 && arguments.length === 1) { throw new TypeError('reduce of empty array with no initial value'); } var i = 0; var result; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i++]; break; } // if array contains no values, no initial value to return if (++i >= length) { throw new TypeError('reduce of empty array with no initial value'); } } while (true); } for (; i < length; i++) { if (i in self) { result = callbackfn(result, self[i], i, object); } } return result; } }, !reduceCoercesToObject); // ES5 15.4.4.22 // http://es5.github.com/#x15.4.4.22 // https://developer.mozilla.org/en/Core_JavaScript_1.5_Reference/Objects/Array/reduceRight var reduceRightCoercesToObject = false; if (ArrayPrototype.reduceRight) { reduceRightCoercesToObject = typeof ArrayPrototype.reduceRight.call('es5', function (_, __, ___, list) { return list; }) === 'object'; } defineProperties(ArrayPrototype, { reduceRight: function reduceRight(callbackfn/*, initial*/) { var object = ES.ToObject(this); var self = splitString && isString(this) ? strSplit(this, '') : object; var length = ES.ToUint32(self.length); // If no callback function or if callback is not a callable function if (!isCallable(callbackfn)) { throw new TypeError('Array.prototype.reduceRight callback must be a function'); } // no value to return if no initial value, empty array if (length === 0 && arguments.length === 1) { throw new TypeError('reduceRight of empty array with no initial value'); } var result; var i = length - 1; if (arguments.length >= 2) { result = arguments[1]; } else { do { if (i in self) { result = self[i--]; break; } // if array contains no values, no initial value to return if (--i < 0) { throw new TypeError('reduceRight of empty array with no initial value'); } } while (true); } if (i < 0) { return result; } do { if (i in self) { result = callbackfn(result, self[i], i, object); } } while (i--); return result; } }, !reduceRightCoercesToObject); // ES5 15.4.4.14 // http://es5.github.com/#x15.4.4.14 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf var hasFirefox2IndexOfBug = ArrayPrototype.indexOf && [0, 1].indexOf(1, 2) !== -1; defineProperties(ArrayPrototype, { indexOf: function indexOf(searchElement/*, fromIndex */) { var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this); var length = ES.ToUint32(self.length); if (length === 0) { return -1; } var i = 0; if (arguments.length > 1) { i = ES.ToInteger(arguments[1]); } // handle negative indices i = i >= 0 ? i : max(0, length + i); for (; i < length; i++) { if (i in self && self[i] === searchElement) { return i; } } return -1; } }, hasFirefox2IndexOfBug); // ES5 15.4.4.15 // http://es5.github.com/#x15.4.4.15 // https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf var hasFirefox2LastIndexOfBug = ArrayPrototype.lastIndexOf && [0, 1].lastIndexOf(0, -3) !== -1; defineProperties(ArrayPrototype, { lastIndexOf: function lastIndexOf(searchElement/*, fromIndex */) { var self = splitString && isString(this) ? strSplit(this, '') : ES.ToObject(this); var length = ES.ToUint32(self.length); if (length === 0) { return -1; } var i = length - 1; if (arguments.length > 1) { i = min(i, ES.ToInteger(arguments[1])); } // handle negative indices i = i >= 0 ? i : length - Math.abs(i); for (; i >= 0; i--) { if (i in self && searchElement === self[i]) { return i; } } return -1; } }, hasFirefox2LastIndexOfBug); // ES5 15.4.4.12 // http://es5.github.com/#x15.4.4.12 var spliceNoopReturnsEmptyArray = (function () { var a = [1, 2]; var result = a.splice(); return a.length === 2 && isArray(result) && result.length === 0; }()); defineProperties(ArrayPrototype, { // Safari 5.0 bug where .splice() returns undefined splice: function splice(start, deleteCount) { if (arguments.length === 0) { return []; } else { return array_splice.apply(this, arguments); } } }, !spliceNoopReturnsEmptyArray); var spliceWorksWithEmptyObject = (function () { var obj = {}; ArrayPrototype.splice.call(obj, 0, 0, 1); return obj.length === 1; }()); defineProperties(ArrayPrototype, { splice: function splice(start, deleteCount) { if (arguments.length === 0) { return []; } var args = arguments; this.length = max(ES.ToInteger(this.length), 0); if (arguments.length > 0 && typeof deleteCount !== 'number') { args = arraySlice(arguments); if (args.length < 2) { push(args, this.length - start); } else { args[1] = ES.ToInteger(deleteCount); } } return array_splice.apply(this, args); } }, !spliceWorksWithEmptyObject); var spliceWorksWithLargeSparseArrays = (function () { // Per https://github.com/es-shims/es5-shim/issues/295 // Safari 7/8 breaks with sparse arrays of size 1e5 or greater var arr = new $Array(1e5); // note: the index MUST be 8 or larger or the test will false pass arr[8] = 'x'; arr.splice(1, 1); // note: this test must be defined *after* the indexOf shim // per https://github.com/es-shims/es5-shim/issues/313 return arr.indexOf('x') === 7; }()); var spliceWorksWithSmallSparseArrays = (function () { // Per https://github.com/es-shims/es5-shim/issues/295 // Opera 12.15 breaks on this, no idea why. var n = 256; var arr = []; arr[n] = 'a'; arr.splice(n + 1, 0, 'b'); return arr[n] === 'a'; }()); defineProperties(ArrayPrototype, { splice: function splice(start, deleteCount) { var O = ES.ToObject(this); var A = []; var len = ES.ToUint32(O.length); var relativeStart = ES.ToInteger(start); var actualStart = relativeStart < 0 ? max((len + relativeStart), 0) : min(relativeStart, len); var actualDeleteCount = min(max(ES.ToInteger(deleteCount), 0), len - actualStart); var k = 0; var from; while (k < actualDeleteCount) { from = $String(actualStart + k); if (owns(O, from)) { A[k] = O[from]; } k += 1; } var items = arraySlice(arguments, 2); var itemCount = items.length; var to; if (itemCount < actualDeleteCount) { k = actualStart; while (k < (len - actualDeleteCount)) { from = $String(k + actualDeleteCount); to = $String(k + itemCount); if (owns(O, from)) { O[to] = O[from]; } else { delete O[to]; } k += 1; } k = len; while (k > (len - actualDeleteCount + itemCount)) { delete O[k - 1]; k -= 1; } } else if (itemCount > actualDeleteCount) { k = len - actualDeleteCount; while (k > actualStart) { from = $String(k + actualDeleteCount - 1); to = $String(k + itemCount - 1); if (owns(O, from)) { O[to] = O[from]; } else { delete O[to]; } k -= 1; } } k = actualStart; for (var i = 0; i < items.length; ++i) { O[k] = items[i]; k += 1; } O.length = len - actualDeleteCount + itemCount; return A; } }, !spliceWorksWithLargeSparseArrays || !spliceWorksWithSmallSparseArrays); var originalJoin = ArrayPrototype.join; var hasStringJoinBug; try { hasStringJoinBug = Array.prototype.join.call('123', ',') !== '1,2,3'; } catch (e) { hasStringJoinBug = true; } if (hasStringJoinBug) { defineProperties(ArrayPrototype, { join: function join(separator) { var sep = typeof separator === 'undefined' ? ',' : separator; return originalJoin.call(isString(this) ? strSplit(this, '') : this, sep); } }, hasStringJoinBug); } var hasJoinUndefinedBug = [1, 2].join(undefined) !== '1,2'; if (hasJoinUndefinedBug) { defineProperties(ArrayPrototype, { join: function join(separator) { var sep = typeof separator === 'undefined' ? ',' : separator; return originalJoin.call(this, sep); } }, hasJoinUndefinedBug); } var pushShim = function push(item) { var O = ES.ToObject(this); var n = ES.ToUint32(O.length); var i = 0; while (i < arguments.length) { O[n + i] = arguments[i]; i += 1; } O.length = n + i; return n + i; }; var pushIsNotGeneric = (function () { var obj = {}; var result = Array.prototype.push.call(obj, undefined); return result !== 1 || obj.length !== 1 || typeof obj[0] !== 'undefined' || !owns(obj, 0); }()); defineProperties(ArrayPrototype, { push: function push(item) { if (isArray(this)) { return array_push.apply(this, arguments); } return pushShim.apply(this, arguments); } }, pushIsNotGeneric); // This fixes a very weird bug in Opera 10.6 when pushing `undefined var pushUndefinedIsWeird = (function () { var arr = []; var result = arr.push(undefined); return result !== 1 || arr.length !== 1 || typeof arr[0] !== 'undefined' || !owns(arr, 0); }()); defineProperties(ArrayPrototype, { push: pushShim }, pushUndefinedIsWeird); // ES5 15.2.3.14 // http://es5.github.io/#x15.4.4.10 // Fix boxed string bug defineProperties(ArrayPrototype, { slice: function (start, end) { var arr = isString(this) ? strSplit(this, '') : this; return arraySliceApply(arr, arguments); } }, splitString); var sortIgnoresNonFunctions = (function () { try { [1, 2].sort(null); [1, 2].sort({}); return true; } catch (e) { /**/ } return false; }()); var sortThrowsOnRegex = (function () { // this is a problem in Firefox 4, in which `typeof /a/ === 'function'` try { [1, 2].sort(/a/); return false; } catch (e) { /**/ } return true; }()); var sortIgnoresUndefined = (function () { // applies in IE 8, for one. try { [1, 2].sort(undefined); return true; } catch (e) { /**/ } return false; }()); defineProperties(ArrayPrototype, { sort: function sort(compareFn) { if (typeof compareFn === 'undefined') { return arraySort(this); } if (!isCallable(compareFn)) { throw new TypeError('Array.prototype.sort callback must be a function'); } return arraySort(this, compareFn); } }, sortIgnoresNonFunctions || !sortIgnoresUndefined || !sortThrowsOnRegex); // // Object // ====== // // ES5 15.2.3.14 // http://es5.github.com/#x15.2.3.14 // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation var hasDontEnumBug = !({ 'toString': null }).propertyIsEnumerable('toString'); var hasProtoEnumBug = function () {}.propertyIsEnumerable('prototype'); var hasStringEnumBug = !owns('x', '0'); var equalsConstructorPrototype = function (o) { var ctor = o.constructor; return ctor && ctor.prototype === o; }; var blacklistedKeys = { $window: true, $console: true, $parent: true, $self: true, $frame: true, $frames: true, $frameElement: true, $webkitIndexedDB: true, $webkitStorageInfo: true, $external: true }; var hasAutomationEqualityBug = (function () { /* globals window */ if (typeof window === 'undefined') { return false; } for (var k in window) { try { if (!blacklistedKeys['$' + k] && owns(window, k) && window[k] !== null && typeof window[k] === 'object') { equalsConstructorPrototype(window[k]); } } catch (e) { return true; } } return false; }()); var equalsConstructorPrototypeIfNotBuggy = function (object) { if (typeof window === 'undefined' || !hasAutomationEqualityBug) { return equalsConstructorPrototype(object); } try { return equalsConstructorPrototype(object); } catch (e) { return false; } }; var dontEnums = [ 'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty', 'isPrototypeOf', 'propertyIsEnumerable', 'constructor' ]; var dontEnumsLength = dontEnums.length; // taken directly from https://github.com/ljharb/is-arguments/blob/master/index.js // can be replaced with require('is-arguments') if we ever use a build process instead var isStandardArguments = function isArguments(value) { return toStr(value) === '[object Arguments]'; }; var isLegacyArguments = function isArguments(value) { return value !== null && typeof value === 'object' && typeof value.length === 'number' && value.length >= 0 && !isArray(value) && isCallable(value.callee); }; var isArguments = isStandardArguments(arguments) ? isStandardArguments : isLegacyArguments; defineProperties($Object, { keys: function keys(object) { var isFn = isCallable(object); var isArgs = isArguments(object); var isObject = object !== null && typeof object === 'object'; var isStr = isObject && isString(object); if (!isObject && !isFn && !isArgs) { throw new TypeError('Object.keys called on a non-object'); } var theKeys = []; var skipProto = hasProtoEnumBug && isFn; if ((isStr && hasStringEnumBug) || isArgs) { for (var i = 0; i < object.length; ++i) { push(theKeys, $String(i)); } } if (!isArgs) { for (var name in object) { if (!(skipProto && name === 'prototype') && owns(object, name)) { push(theKeys, $String(name)); } } } if (hasDontEnumBug) { var skipConstructor = equalsConstructorPrototypeIfNotBuggy(object); for (var j = 0; j < dontEnumsLength; j++) { var dontEnum = dontEnums[j]; if (!(skipConstructor && dontEnum === 'constructor') && owns(object, dontEnum)) { push(theKeys, dontEnum); } } } return theKeys; } }); var keysWorksWithArguments = $Object.keys && (function () { // Safari 5.0 bug return $Object.keys(arguments).length === 2; }(1, 2)); var keysHasArgumentsLengthBug = $Object.keys && (function () { var argKeys = $Object.keys(arguments); return arguments.length !== 1 || argKeys.length !== 1 || argKeys[0] !== 1; }(1)); var originalKeys = $Object.keys; defineProperties($Object, { keys: function keys(object) { if (isArguments(object)) { return originalKeys(arraySlice(object)); } else { return originalKeys(object); } } }, !keysWorksWithArguments || keysHasArgumentsLengthBug); // // Date // ==== // // ES5 15.9.5.43 // http://es5.github.com/#x15.9.5.43 // This function returns a String value represent the instance in time // represented by this Date object. The format of the String is the Date Time // string format defined in 15.9.1.15. All fields are present in the String. // The time zone is always UTC, denoted by the suffix Z. If the time value of // this object is not a finite Number a RangeError exception is thrown. var negativeDate = -62198755200000; var negativeYearString = '-000001'; var hasNegativeDateBug = Date.prototype.toISOString && new Date(negativeDate).toISOString().indexOf(negativeYearString) === -1; var hasSafari51DateBug = Date.prototype.toISOString && new Date(-1).toISOString() !== '1969-12-31T23:59:59.999Z'; defineProperties(Date.prototype, { toISOString: function toISOString() { var result, length, value, year, month; if (!isFinite(this)) { throw new RangeError('Date.prototype.toISOString called on non-finite value.'); } year = this.getUTCFullYear(); month = this.getUTCMonth(); // see https://github.com/es-shims/es5-shim/issues/111 year += Math.floor(month / 12); month = (month % 12 + 12) % 12; // the date time string format is specified in 15.9.1.15. result = [month + 1, this.getUTCDate(), this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()]; year = ( (year < 0 ? '-' : (year > 9999 ? '+' : '')) + strSlice('00000' + Math.abs(year), (0 <= year && year <= 9999) ? -4 : -6) ); length = result.length; while (length--) { value = result[length]; // pad months, days, hours, minutes, and seconds to have two // digits. if (value < 10) { result[length] = '0' + value; } } // pad milliseconds to have three digits. return ( year + '-' + arraySlice(result, 0, 2).join('-') + 'T' + arraySlice(result, 2).join(':') + '.' + strSlice('000' + this.getUTCMilliseconds(), -3) + 'Z' ); } }, hasNegativeDateBug || hasSafari51DateBug); // ES5 15.9.5.44 // http://es5.github.com/#x15.9.5.44 // This function provides a String representation of a Date object for use by // JSON.stringify (15.12.3). var dateToJSONIsSupported = (function () { try { return Date.prototype.toJSON && new Date(NaN).toJSON() === null && new Date(negativeDate).toJSON().indexOf(negativeYearString) !== -1 && Date.prototype.toJSON.call({ // generic toISOString: function () { return true; } }); } catch (e) { return false; } }()); if (!dateToJSONIsSupported) { Date.prototype.toJSON = function toJSON(key) { // When the toJSON method is called with argument key, the following // steps are taken: // 1. Let O be the result of calling ToObject, giving it the this // value as its argument. // 2. Let tv be ES.ToPrimitive(O, hint Number). var O = $Object(this); var tv = ES.ToPrimitive(O); // 3. If tv is a Number and is not finite, return null. if (typeof tv === 'number' && !isFinite(tv)) { return null; } // 4. Let toISO be the result of calling the [[Get]] internal method of // O with argument "toISOString". var toISO = O.toISOString; // 5. If IsCallable(toISO) is false, throw a TypeError exception. if (!isCallable(toISO)) { throw new TypeError('toISOString property is not callable'); } // 6. Return the result of calling the [[Call]] internal method of // toISO with O as the this value and an empty argument list. return toISO.call(O); // NOTE 1 The argument is ignored. // NOTE 2 The toJSON function is intentionally generic; it does not // require that its this value be a Date object. Therefore, it can be // transferred to other kinds of objects for use as a method. However, // it does require that any such object have a toISOString method. An // object is free to use the argument key to filter its // stringification. }; } // ES5 15.9.4.2 // http://es5.github.com/#x15.9.4.2 // based on work shared by Daniel Friesen (dantman) // http://gist.github.com/303249 var supportsExtendedYears = Date.parse('+033658-09-27T01:46:40.000Z') === 1e15; var acceptsInvalidDates = !isNaN(Date.parse('2012-04-04T24:00:00.500Z')) || !isNaN(Date.parse('2012-11-31T23:59:59.000Z')) || !isNaN(Date.parse('2012-12-31T23:59:60.000Z')); var doesNotParseY2KNewYear = isNaN(Date.parse('2000-01-01T00:00:00.000Z')); if (doesNotParseY2KNewYear || acceptsInvalidDates || !supportsExtendedYears) { // XXX global assignment won't work in embeddings that use // an alternate object for the context. /* global Date: true */ /* eslint-disable no-undef */ var maxSafeUnsigned32Bit = Math.pow(2, 31) - 1; var hasSafariSignedIntBug = isActualNaN(new Date(1970, 0, 1, 0, 0, 0, maxSafeUnsigned32Bit + 1).getTime()); Date = (function (NativeDate) { /* eslint-enable no-undef */ // Date.length === 7 var DateShim = function Date(Y, M, D, h, m, s, ms) { var length = arguments.length; var date; if (this instanceof NativeDate) { var seconds = s; var millis = ms; if (hasSafariSignedIntBug && length >= 7 && ms > maxSafeUnsigned32Bit) { // work around a Safari 8/9 bug where it treats the seconds as signed var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit; var sToShift = Math.floor(msToShift / 1e3); seconds += sToShift; millis -= sToShift * 1e3; } date = length === 1 && $String(Y) === Y ? // isString(Y) // We explicitly pass it through parse: new NativeDate(DateShim.parse(Y)) : // We have to manually make calls depending on argument // length here length >= 7 ? new NativeDate(Y, M, D, h, m, seconds, millis) : length >= 6 ? new NativeDate(Y, M, D, h, m, seconds) : length >= 5 ? new NativeDate(Y, M, D, h, m) : length >= 4 ? new NativeDate(Y, M, D, h) : length >= 3 ? new NativeDate(Y, M, D) : length >= 2 ? new NativeDate(Y, M) : length >= 1 ? new NativeDate(Y) : new NativeDate(); } else { date = NativeDate.apply(this, arguments); } if (!isPrimitive(date)) { // Prevent mixups with unfixed Date object defineProperties(date, { constructor: DateShim }, true); } return date; }; // 15.9.1.15 Date Time String Format. var isoDateExpression = new RegExp('^' + '(\\d{4}|[+-]\\d{6})' + // four-digit year capture or sign + // 6-digit extended year '(?:-(\\d{2})' + // optional month capture '(?:-(\\d{2})' + // optional day capture '(?:' + // capture hours:minutes:seconds.milliseconds 'T(\\d{2})' + // hours capture ':(\\d{2})' + // minutes capture '(?:' + // optional :seconds.milliseconds ':(\\d{2})' + // seconds capture '(?:(\\.\\d{1,}))?' + // milliseconds capture ')?' + '(' + // capture UTC offset component 'Z|' + // UTC capture '(?:' + // offset specifier +/-hours:minutes '([-+])' + // sign capture '(\\d{2})' + // hours offset capture ':(\\d{2})' + // minutes offset capture ')' + ')?)?)?)?' + '$'); var months = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365]; var dayFromMonth = function dayFromMonth(year, month) { var t = month > 1 ? 1 : 0; return ( months[month] + Math.floor((year - 1969 + t) / 4) - Math.floor((year - 1901 + t) / 100) + Math.floor((year - 1601 + t) / 400) + 365 * (year - 1970) ); }; var toUTC = function toUTC(t) { var s = 0; var ms = t; if (hasSafariSignedIntBug && ms > maxSafeUnsigned32Bit) { // work around a Safari 8/9 bug where it treats the seconds as signed var msToShift = Math.floor(ms / maxSafeUnsigned32Bit) * maxSafeUnsigned32Bit; var sToShift = Math.floor(msToShift / 1e3); s += sToShift; ms -= sToShift * 1e3; } return $Number(new NativeDate(1970, 0, 1, 0, 0, s, ms)); }; // Copy any custom methods a 3rd party library may have added for (var key in NativeDate) { if (owns(NativeDate, key)) { DateShim[key] = NativeDate[key]; } } // Copy "native" methods explicitly; they may be non-enumerable defineProperties(DateShim, { now: NativeDate.now, UTC: NativeDate.UTC }, true); DateShim.prototype = NativeDate.prototype; defineProperties(DateShim.prototype, { constructor: DateShim }, true); // Upgrade Date.parse to handle simplified ISO 8601 strings var parseShim = function parse(string) { var match = isoDateExpression.exec(string); if (match) { // parse months, days, hours, minutes, seconds, and milliseconds // provide default values if necessary // parse the UTC offset component var year = $Number(match[1]), month = $Number(match[2] || 1) - 1, day = $Number(match[3] || 1) - 1, hour = $Number(match[4] || 0), minute = $Number(match[5] || 0), second = $Number(match[6] || 0), millisecond = Math.floor($Number(match[7] || 0) * 1000), // When time zone is missed, local offset should be used // (ES 5.1 bug) // see https://bugs.ecmascript.org/show_bug.cgi?id=112 isLocalTime = Boolean(match[4] && !match[8]), signOffset = match[9] === '-' ? 1 : -1, hourOffset = $Number(match[10] || 0), minuteOffset = $Number(match[11] || 0), result; var hasMinutesOrSecondsOrMilliseconds = minute > 0 || second > 0 || millisecond > 0; if ( hour < (hasMinutesOrSecondsOrMilliseconds ? 24 : 25) && minute < 60 && second < 60 && millisecond < 1000 && month > -1 && month < 12 && hourOffset < 24 && minuteOffset < 60 && // detect invalid offsets day > -1 && day < (dayFromMonth(year, month + 1) - dayFromMonth(year, month)) ) { result = ( (dayFromMonth(year, month) + day) * 24 + hour + hourOffset * signOffset ) * 60; result = ( (result + minute + minuteOffset * signOffset) * 60 + second ) * 1000 + millisecond; if (isLocalTime) { result = toUTC(result); } if (-8.64e15 <= result && result <= 8.64e15) { return result; } } return NaN; } return NativeDate.parse.apply(this, arguments); }; defineProperties(DateShim, { parse: parseShim }); return DateShim; }(Date)); /* global Date: false */ } // ES5 15.9.4.4 // http://es5.github.com/#x15.9.4.4 if (!Date.now) { Date.now = function now() { return new Date().getTime(); }; } // // Number // ====== // // ES5.1 15.7.4.5 // http://es5.github.com/#x15.7.4.5 var hasToFixedBugs = NumberPrototype.toFixed && ( (0.00008).toFixed(3) !== '0.000' || (0.9).toFixed(0) !== '1' || (1.255).toFixed(2) !== '1.25' || (1000000000000000128).toFixed(0) !== '1000000000000000128' ); var toFixedHelpers = { base: 1e7, size: 6, data: [0, 0, 0, 0, 0, 0], multiply: function multiply(n, c) { var i = -1; var c2 = c; while (++i < toFixedHelpers.size) { c2 += n * toFixedHelpers.data[i]; toFixedHelpers.data[i] = c2 % toFixedHelpers.base; c2 = Math.floor(c2 / toFixedHelpers.base); } }, divide: function divide(n) { var i = toFixedHelpers.size, c = 0; while (--i >= 0) { c += toFixedHelpers.data[i]; toFixedHelpers.data[i] = Math.floor(c / n); c = (c % n) * toFixedHelpers.base; } }, numToString: function numToString() { var i = toFixedHelpers.size; var s = ''; while (--i >= 0) { if (s !== '' || i === 0 || toFixedHelpers.data[i] !== 0) { var t = $String(toFixedHelpers.data[i]); if (s === '') { s = t; } else { s += strSlice('0000000', 0, 7 - t.length) + t; } } } return s; }, pow: function pow(x, n, acc) { return (n === 0 ? acc : (n % 2 === 1 ? pow(x, n - 1, acc * x) : pow(x * x, n / 2, acc))); }, log: function log(x) { var n = 0; var x2 = x; while (x2 >= 4096) { n += 12; x2 /= 4096; } while (x2 >= 2) { n += 1; x2 /= 2; } return n; } }; var toFixedShim = function toFixed(fractionDigits) { var f, x, s, m, e, z, j, k; // Test for NaN and round fractionDigits down f = $Number(fractionDigits); f = isActualNaN(f) ? 0 : Math.floor(f); if (f < 0 || f > 20) { throw new RangeError('Number.toFixed called with invalid number of decimals'); } x = $Number(this); if (isActualNaN(x)) { return 'NaN'; } // If it is too big or small, return the string value of the number if (x <= -1e21 || x >= 1e21) { return $String(x); } s = ''; if (x < 0) { s = '-'; x = -x; } m = '0'; if (x > 1e-21) { // 1e-21 < x < 1e21 // -70 < log2(x) < 70 e = toFixedHelpers.log(x * toFixedHelpers.pow(2, 69, 1)) - 69; z = (e < 0 ? x * toFixedHelpers.pow(2, -e, 1) : x / toFixedHelpers.pow(2, e, 1)); z *= 0x10000000000000; // Math.pow(2, 52); e = 52 - e; // -18 < e < 122 // x = z / 2 ^ e if (e > 0) { toFixedHelpers.multiply(0, z); j = f; while (j >= 7) { toFixedHelpers.multiply(1e7, 0); j -= 7; } toFixedHelpers.multiply(toFixedHelpers.pow(10, j, 1), 0); j = e - 1; while (j >= 23) { toFixedHelpers.divide(1 << 23); j -= 23; } toFixedHelpers.divide(1 << j); toFixedHelpers.multiply(1, 1); toFixedHelpers.divide(2); m = toFixedHelpers.numToString(); } else { toFixedHelpers.multiply(0, z); toFixedHelpers.multiply(1 << (-e), 0); m = toFixedHelpers.numToString() + strSlice('0.00000000000000000000', 2, 2 + f); } } if (f > 0) { k = m.length; if (k <= f) { m = s + strSlice('0.0000000000000000000', 0, f - k + 2) + m; } else { m = s + strSlice(m, 0, k - f) + '.' + strSlice(m, k - f); } } else { m = s + m; } return m; }; defineProperties(NumberPrototype, { toFixed: toFixedShim }, hasToFixedBugs); var hasToPrecisionUndefinedBug = (function () { try { return 1.0.toPrecision(undefined) === '1'; } catch (e) { return true; } }()); var originalToPrecision = NumberPrototype.toPrecision; defineProperties(NumberPrototype, { toPrecision: function toPrecision(precision) { return typeof precision === 'undefined' ? originalToPrecision.call(this) : originalToPrecision.call(this, precision); } }, hasToPrecisionUndefinedBug); // // String // ====== // // ES5 15.5.4.14 // http://es5.github.com/#x15.5.4.14 // [bugfix, IE lt 9, firefox 4, Konqueror, Opera, obscure browsers] // Many browsers do not split properly with regular expressions or they // do not perform the split correctly under obscure conditions. // See http://blog.stevenlevithan.com/archives/cross-browser-split // I've tested in many browsers and this seems to cover the deviant ones: // 'ab'.split(/(?:ab)*/) should be ["", ""], not [""] // '.'.split(/(.?)(.?)/) should be ["", ".", "", ""], not ["", ""] // 'tesst'.split(/(s)*/) should be ["t", undefined, "e", "s", "t"], not // [undefined, "t", undefined, "e", ...] // ''.split(/.?/) should be [], not [""] // '.'.split(/()()/) should be ["."], not ["", "", "."] if ( 'ab'.split(/(?:ab)*/).length !== 2 || '.'.split(/(.?)(.?)/).length !== 4 || 'tesst'.split(/(s)*/)[1] === 't' || 'test'.split(/(?:)/, -1).length !== 4 || ''.split(/.?/).length || '.'.split(/()()/).length > 1 ) { (function () { var compliantExecNpcg = typeof (/()??/).exec('')[1] === 'undefined'; // NPCG: nonparticipating capturing group var maxSafe32BitInt = Math.pow(2, 32) - 1; StringPrototype.split = function (separator, limit) { var string = String(this); if (typeof separator === 'undefined' && limit === 0) { return []; } // If `separator` is not a regex, use native split if (!isRegex(separator)) { return strSplit(this, separator, limit); } var output = []; var flags = (separator.ignoreCase ? 'i' : '') + (separator.multiline ? 'm' : '') + (separator.unicode ? 'u' : '') + // in ES6 (separator.sticky ? 'y' : ''), // Firefox 3+ and ES6 lastLastIndex = 0, // Make `global` and avoid `lastIndex` issues by working with a copy separator2, match, lastIndex, lastLength; var separatorCopy = new RegExp(separator.source, flags + 'g'); if (!compliantExecNpcg) { // Doesn't need flags gy, but they don't hurt separator2 = new RegExp('^' + separatorCopy.source + '$(?!\\s)', flags); } /* Values for `limit`, per the spec: * If undefined: 4294967295 // maxSafe32BitInt * If 0, Infinity, or NaN: 0 * If positive number: limit = Math.floor(limit); if (limit > 4294967295) limit -= 4294967296; * If negative number: 4294967296 - Math.floor(Math.abs(limit)) * If other: Type-convert, then use the above rules */ var splitLimit = typeof limit === 'undefined' ? maxSafe32BitInt : ES.ToUint32(limit); match = separatorCopy.exec(string); while (match) { // `separatorCopy.lastIndex` is not reliable cross-browser lastIndex = match.index + match[0].length; if (lastIndex > lastLastIndex) { push(output, strSlice(string, lastLastIndex, match.index)); // Fix browsers whose `exec` methods don't consistently return `undefined` for // nonparticipating capturing groups if (!compliantExecNpcg && match.length > 1) { /* eslint-disable no-loop-func */ match[0].replace(separator2, function () { for (var i = 1; i < arguments.length - 2; i++) { if (typeof arguments[i] === 'undefined') { match[i] = void 0; } } }); /* eslint-enable no-loop-func */ } if (match.length > 1 && match.index < string.length) { array_push.apply(output, arraySlice(match, 1)); } lastLength = match[0].length; lastLastIndex = lastIndex; if (output.length >= splitLimit) { break; } } if (separatorCopy.lastIndex === match.index) { separatorCopy.lastIndex++; // Avoid an infinite loop } match = separatorCopy.exec(string); } if (lastLastIndex === string.length) { if (lastLength || !separatorCopy.test('')) { push(output, ''); } } else { push(output, strSlice(string, lastLastIndex)); } return output.length > splitLimit ? strSlice(output, 0, splitLimit) : output; }; }()); // [bugfix, chrome] // If separator is undefined, then the result array contains just one String, // which is the this value (converted to a String). If limit is not undefined, // then the output array is truncated so that it contains no more than limit // elements. // "0".split(undefined, 0) -> [] } else if ('0'.split(void 0, 0).length) { StringPrototype.split = function split(separator, limit) { if (typeof separator === 'undefined' && limit === 0) { return []; } return strSplit(this, separator, limit); }; } var str_replace = StringPrototype.replace; var replaceReportsGroupsCorrectly = (function () { var groups = []; 'x'.replace(/x(.)?/g, function (match, group) { push(groups, group); }); return groups.length === 1 && typeof groups[0] === 'undefined'; }()); if (!replaceReportsGroupsCorrectly) { StringPrototype.replace = function replace(searchValue, replaceValue) { var isFn = isCallable(replaceValue); var hasCapturingGroups = isRegex(searchValue) && (/\)[*?]/).test(searchValue.source); if (!isFn || !hasCapturingGroups) { return str_replace.call(this, searchValue, replaceValue); } else { var wrappedReplaceValue = function (match) { var length = arguments.length; var originalLastIndex = searchValue.lastIndex; searchValue.lastIndex = 0; var args = searchValue.exec(match) || []; searchValue.lastIndex = originalLastIndex; push(args, arguments[length - 2], arguments[length - 1]); return replaceValue.apply(this, args); }; return str_replace.call(this, searchValue, wrappedReplaceValue); } }; } // ECMA-262, 3rd B.2.3 // Not an ECMAScript standard, although ECMAScript 3rd Edition has a // non-normative section suggesting uniform semantics and it should be // normalized across all browsers // [bugfix, IE lt 9] IE < 9 substr() with negative value not working in IE var string_substr = StringPrototype.substr; var hasNegativeSubstrBug = ''.substr && '0b'.substr(-1) !== 'b'; defineProperties(StringPrototype, { substr: function substr(start, length) { var normalizedStart = start; if (start < 0) { normalizedStart = max(this.length + start, 0); } return string_substr.call(this, normalizedStart, length); } }, hasNegativeSubstrBug); // ES5 15.5.4.20 // whitespace from: http://es5.github.io/#x15.5.4.20 var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + '\u2029\uFEFF'; var zeroWidth = '\u200b'; var wsRegexChars = '[' + ws + ']'; var trimBeginRegexp = new RegExp('^' + wsRegexChars + wsRegexChars + '*'); var trimEndRegexp = new RegExp(wsRegexChars + wsRegexChars + '*$'); var hasTrimWhitespaceBug = StringPrototype.trim && (ws.trim() || !zeroWidth.trim()); defineProperties(StringPrototype, { // http://blog.stevenlevithan.com/archives/faster-trim-javascript // http://perfectionkills.com/whitespace-deviations/ trim: function trim() { if (typeof this === 'undefined' || this === null) { throw new TypeError("can't convert " + this + ' to object'); } return $String(this).replace(trimBeginRegexp, '').replace(trimEndRegexp, ''); } }, hasTrimWhitespaceBug); var hasLastIndexBug = StringPrototype.lastIndexOf && 'abcあい'.lastIndexOf('あい', 2) !== -1; defineProperties(StringPrototype, { lastIndexOf: function lastIndexOf(searchString) { if (typeof this === 'undefined' || this === null) { throw new TypeError("can't convert " + this + ' to object'); } var S = $String(this); var searchStr = $String(searchString); var numPos = arguments.length > 1 ? $Number(arguments[1]) : NaN; var pos = isActualNaN(numPos) ? Infinity : ES.ToInteger(numPos); var start = min(max(pos, 0), S.length); var searchLen = searchStr.length; var k = start + searchLen; while (k > 0) { k = max(0, k - searchLen); var index = strIndexOf(strSlice(S, k, start + searchLen), searchStr); if (index !== -1) { return k + index; } } return -1; } }, hasLastIndexBug); var originalLastIndexOf = StringPrototype.lastIndexOf; defineProperties(StringPrototype, { lastIndexOf: function lastIndexOf(searchString) { return originalLastIndexOf.apply(this, arguments); } }, StringPrototype.lastIndexOf.length !== 1); // ES-5 15.1.2.2 /* eslint-disable radix */ if (parseInt(ws + '08') !== 8 || parseInt(ws + '0x16') !== 22) { /* eslint-enable radix */ /* global parseInt: true */ parseInt = (function (origParseInt) { var hexRegex = /^[\-+]?0[xX]/; return function parseInt(str, radix) { var string = $String(str).trim(); var defaultedRadix = $Number(radix) || (hexRegex.test(string) ? 16 : 10); return origParseInt(string, defaultedRadix); }; }(parseInt)); } if (String(new RangeError('test')) !== 'RangeError: test') { var errorToStringShim = function toString() { if (typeof this === 'undefined' || this === null) { throw new TypeError("can't convert " + this + ' to object'); } var name = this.name; if (typeof name === 'undefined') { name = 'Error'; } else if (typeof name !== 'string') { name = $String(name); } var msg = this.message; if (typeof msg === 'undefined') { msg = ''; } else if (typeof msg !== 'string') { msg = $String(msg); } if (!name) { return msg; } if (!msg) { return name; } return name + ': ' + msg; }; // can't use defineProperties here because of toString enumeration issue in IE <= 8 Error.prototype.toString = errorToStringShim; } if (supportsDescriptors) { var ensureNonEnumerable = function (obj, prop) { if (isEnum(obj, prop)) { var desc = Object.getOwnPropertyDescriptor(obj, prop); desc.enumerable = false; Object.defineProperty(obj, prop, desc); } }; ensureNonEnumerable(Error.prototype, 'message'); if (Error.prototype.message !== '') { Error.prototype.message = ''; } ensureNonEnumerable(Error.prototype, 'name'); } if (String(/a/mig) !== '/a/gim') { var regexToString = function toString() { var str = '/' + this.source + '/'; if (this.global) { str += 'g'; } if (this.ignoreCase) { str += 'i'; } if (this.multiline) { str += 'm'; } return str; }; // can't use defineProperties here because of toString enumeration issue in IE <= 8 RegExp.prototype.toString = regexToString; } })); es5-shim-4.4.1/es5-shim.map000066400000000000000000000767471263422513500153330ustar00rootroot00000000000000{"version":3,"sources":["es5-shim.js"],"names":["root","factory","define","amd","exports","module","returnExports","this","$Array","Array","ArrayPrototype","prototype","$Object","Object","ObjectPrototype","FunctionPrototype","Function","$String","String","StringPrototype","$Number","Number","NumberPrototype","array_slice","slice","array_splice","splice","array_push","push","array_unshift","unshift","array_concat","concat","call","apply","max","Math","min","to_string","toString","hasToStringTag","Symbol","toStringTag","isCallable","fnToStr","tryFunctionObject","value","e","fnClass","genClass","strClass","isRegex","regexExec","RegExp","exec","tryRegexExec","regexClass","isString","strValue","valueOf","tryStringObject","stringClass","supportsDescriptors","defineProperty","obj","enumerable","_","x","defineProperties","has","object","name","method","forceAssign","configurable","writable","map","hasOwnProperty","isPrimitive","input","type","isActualNaN","isNaN","ES","ToInteger","num","n","floor","abs","ToPrimitive","val","toStr","TypeError","ToObject","o","ToUint32","Empty","bind","that","target","args","arguments","bound","binder","result","boundLength","length","boundArgs","i","join","owns","arraySlice","arraySliceApply","strSlice","strSplit","split","strIndexOf","indexOf","isEnum","propertyIsEnumerable","arraySort","sort","isArray","hasUnshiftReturnValueBug","boxedString","splitString","properlyBoxesContext","properlyBoxed","properlyBoxesNonStrict","properlyBoxesStrict","__","context","forEach","callbackfn","self","T","filter","every","some","reduceCoercesToObject","reduce","___","list","reduceRightCoercesToObject","reduceRight","hasFirefox2IndexOfBug","searchElement","hasFirefox2LastIndexOfBug","lastIndexOf","spliceNoopReturnsEmptyArray","a","start","deleteCount","spliceWorksWithEmptyObject","spliceWorksWithLargeSparseArrays","arr","spliceWorksWithSmallSparseArrays","O","A","len","relativeStart","actualStart","actualDeleteCount","k","from","items","itemCount","to","originalJoin","hasStringJoinBug","separator","sep","hasJoinUndefinedBug","undefined","pushShim","item","pushIsNotGeneric","pushUndefinedIsWeird","end","sortIgnoresNonFunctions","sortThrowsOnRegex","sortIgnoresUndefined","compareFn","hasDontEnumBug","hasProtoEnumBug","hasStringEnumBug","equalsConstructorPrototype","ctor","constructor","blacklistedKeys","$window","$console","$parent","$self","$frame","$frames","$frameElement","$webkitIndexedDB","$webkitStorageInfo","$external","hasAutomationEqualityBug","window","equalsConstructorPrototypeIfNotBuggy","dontEnums","dontEnumsLength","isStandardArguments","isArguments","isLegacyArguments","callee","keys","isFn","isArgs","isObject","isStr","theKeys","skipProto","skipConstructor","j","dontEnum","keysWorksWithArguments","keysHasArgumentsLengthBug","argKeys","originalKeys","negativeDate","negativeYearString","hasNegativeDateBug","Date","toISOString","hasSafari51DateBug","year","month","isFinite","RangeError","getUTCFullYear","getUTCMonth","getUTCDate","getUTCHours","getUTCMinutes","getUTCSeconds","getUTCMilliseconds","dateToJSONIsSupported","toJSON","NaN","key","tv","toISO","supportsExtendedYears","parse","acceptsInvalidDates","doesNotParseY2KNewYear","maxSafeUnsigned32Bit","pow","hasSafariSignedIntBug","getTime","NativeDate","DateShim","Y","M","D","h","m","s","ms","date","seconds","millis","msToShift","sToShift","isoDateExpression","months","dayFromMonth","t","toUTC","now","UTC","parseShim","string","match","day","hour","minute","second","millisecond","isLocalTime","Boolean","signOffset","hourOffset","minuteOffset","hasMinutesOrSecondsOrMilliseconds","hasToFixedBugs","toFixed","toFixedHelpers","base","size","data","multiply","c","c2","divide","numToString","acc","log","x2","toFixedShim","fractionDigits","f","z","hasToPrecisionUndefinedBug","toPrecision","originalToPrecision","precision","compliantExecNpcg","maxSafe32BitInt","limit","output","flags","ignoreCase","multiline","unicode","sticky","lastLastIndex","separator2","lastIndex","lastLength","separatorCopy","source","splitLimit","index","replace","test","str_replace","replaceReportsGroupsCorrectly","groups","group","searchValue","replaceValue","hasCapturingGroups","wrappedReplaceValue","originalLastIndex","string_substr","substr","hasNegativeSubstrBug","normalizedStart","ws","zeroWidth","wsRegexChars","trimBeginRegexp","trimEndRegexp","hasTrimWhitespaceBug","trim","hasLastIndexBug","searchString","S","searchStr","numPos","pos","Infinity","searchLen","originalLastIndexOf","parseInt","origParseInt","hexRegex","str","radix","defaultedRadix","errorToStringShim","msg","message","Error","ensureNonEnumerable","prop","desc","getOwnPropertyDescriptor","regexToString","global"],"mappings":"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"}es5-shim-4.4.1/es5-shim.min.js000066400000000000000000000513151263422513500157340ustar00rootroot00000000000000/*! * https://github.com/es-shims/es5-shim * @license es5-shim Copyright 2009-2015 by contributors, MIT License * see https://github.com/es-shims/es5-shim/blob/v4.4.1/LICENSE */ (function(r,t){"use strict";if(typeof define==="function"&&define.amd){define(t)}else if(typeof exports==="object"){module.exports=t()}else{r.returnExports=t()}})(this,function(){var r=Array;var t=r.prototype;var e=Object;var n=e.prototype;var i=Function.prototype;var a=String;var o=a.prototype;var u=Number;var f=u.prototype;var l=t.slice;var s=t.splice;var c=t.push;var v=t.unshift;var p=t.concat;var h=i.call;var g=i.apply;var y=Math.max;var d=Math.min;var m=n.toString;var w=typeof Symbol==="function"&&typeof Symbol.toStringTag==="symbol";var b;var T=Function.prototype.toString,x=function tryFunctionObject(r){try{T.call(r);return true}catch(t){return false}},O="[object Function]",S="[object GeneratorFunction]";b=function isCallable(r){if(typeof r!=="function"){return false}if(w){return x(r)}var t=m.call(r);return t===O||t===S};var E;var j=RegExp.prototype.exec,I=function tryRegexExec(r){try{j.call(r);return true}catch(t){return false}},D="[object RegExp]";E=function isRegex(r){if(typeof r!=="object"){return false}return w?I(r):m.call(r)===D};var N;var k=String.prototype.valueOf,M=function tryStringObject(r){try{k.call(r);return true}catch(t){return false}},U="[object String]";N=function isString(r){if(typeof r==="string"){return true}if(typeof r!=="object"){return false}return w?M(r):m.call(r)===U};var R=e.defineProperty&&function(){try{var r={};e.defineProperty(r,"x",{enumerable:false,value:r});for(var t in r){return false}return r.x===r}catch(n){return false}}();var F=function(r){var t;if(R){t=function(r,t,n,i){if(!i&&t in r){return}e.defineProperty(r,t,{configurable:true,enumerable:false,writable:true,value:n})}}else{t=function(r,t,e,n){if(!n&&t in r){return}r[t]=e}}return function defineProperties(e,n,i){for(var a in n){if(r.call(n,a)){t(e,a,n[a],i)}}}}(n.hasOwnProperty);var A=function isPrimitive(r){var t=typeof r;return r===null||t!=="object"&&t!=="function"};var P=u.isNaN||function(r){return r!==r};var $={ToInteger:function ToInteger(r){var t=+r;if(P(t)){t=0}else if(t!==0&&t!==1/0&&t!==-(1/0)){t=(t>0||-1)*Math.floor(Math.abs(t))}return t},ToPrimitive:function ToPrimitive(r){var t,e,n;if(A(r)){return r}e=r.valueOf;if(b(e)){t=e.call(r);if(A(t)){return t}}n=r.toString;if(b(n)){t=n.call(r);if(A(t)){return t}}throw new TypeError},ToObject:function(r){if(r==null){throw new TypeError("can't convert "+r+" to object")}return e(r)},ToUint32:function ToUint32(r){return r>>>0}};var C=function Empty(){};F(i,{bind:function bind(r){var t=this;if(!b(t)){throw new TypeError("Function.prototype.bind called on incompatible "+t)}var n=l.call(arguments,1);var i;var a=function(){if(this instanceof i){var a=t.apply(this,p.call(n,l.call(arguments)));if(e(a)===a){return a}return this}else{return t.apply(r,p.call(n,l.call(arguments)))}};var o=y(0,t.length-n.length);var u=[];for(var f=0;f1){a=arguments[1]}if(!b(r)){throw new TypeError("Array.prototype.forEach callback must be a function")}while(++n1){o=arguments[1]}if(!b(t)){throw new TypeError("Array.prototype.map callback must be a function")}for(var u=0;u1){o=arguments[1]}if(!b(r)){throw new TypeError("Array.prototype.filter callback must be a function")}for(var u=0;u1){i=arguments[1]}if(!b(r)){throw new TypeError("Array.prototype.every callback must be a function")}for(var a=0;a1){i=arguments[1]}if(!b(r)){throw new TypeError("Array.prototype.some callback must be a function")}for(var a=0;a=2){a=arguments[1]}else{do{if(i in e){a=e[i++];break}if(++i>=n){throw new TypeError("reduce of empty array with no initial value")}}while(true)}for(;i=2){i=arguments[1]}else{do{if(a in e){i=e[a--];break}if(--a<0){throw new TypeError("reduceRight of empty array with no initial value")}}while(true)}if(a<0){return i}do{if(a in e){i=r(i,e[a],a,t)}}while(a--);return i}},!tr);var er=t.indexOf&&[0,1].indexOf(1,2)!==-1;F(t,{indexOf:function indexOf(r){var t=W&&N(this)?H(this,""):$.ToObject(this);var e=$.ToUint32(t.length);if(e===0){return-1}var n=0;if(arguments.length>1){n=$.ToInteger(arguments[1])}n=n>=0?n:y(0,e+n);for(;n1){n=d(n,$.ToInteger(arguments[1]))}n=n>=0?n:e-Math.abs(n);for(;n>=0;n--){if(n in t&&r===t[n]){return n}}return-1}},nr);var ir=function(){var r=[1,2];var t=r.splice();return r.length===2&&K(t)&&t.length===0}();F(t,{splice:function splice(r,t){if(arguments.length===0){return[]}else{return s.apply(this,arguments)}}},!ir);var ar=function(){var r={};t.splice.call(r,0,0,1);return r.length===1}();F(t,{splice:function splice(r,t){if(arguments.length===0){return[]}var e=arguments;this.length=y($.ToInteger(this.length),0);if(arguments.length>0&&typeof t!=="number"){e=z(arguments);if(e.length<2){X(e,this.length-r)}else{e[1]=$.ToInteger(t)}}return s.apply(this,e)}},!ar);var or=function(){var t=new r(1e5);t[8]="x";t.splice(1,1);return t.indexOf("x")===7}();var ur=function(){var r=256;var t=[];t[r]="a";t.splice(r+1,0,"b");return t[r]==="a"}();F(t,{splice:function splice(r,t){var e=$.ToObject(this);var n=[];var i=$.ToUint32(e.length);var o=$.ToInteger(r);var u=o<0?y(i+o,0):d(o,i);var f=d(y($.ToInteger(t),0),i-u);var l=0;var s;while(li-f+v){delete e[l-1];l-=1}}else if(v>f){l=i-f;while(l>u){s=a(l+f-1);p=a(l+v-1);if(Z(e,s)){e[p]=e[s]}else{delete e[p]}l-=1}}l=u;for(var h=0;h=0&&!K(r)&&b(r.callee)};var Nr=Ir(arguments)?Ir:Dr;F(e,{keys:function keys(r){var t=b(r);var e=Nr(r);var n=r!==null&&typeof r==="object";var i=n&&N(r);if(!n&&!t&&!e){throw new TypeError("Object.keys called on a non-object")}var o=[];var u=wr&&t;if(i&&br||e){for(var f=0;f9999?"+":"")+G("00000"+Math.abs(n),0<=n&&n<=9999?-4:-6);t=r.length;while(t--){e=r[t];if(e<10){r[t]="0"+e}}return n+"-"+z(r,0,2).join("-")+"T"+z(r,2).join(":")+"."+G("000"+this.getUTCMilliseconds(),-3)+"Z"}},Ar||Pr);var $r=function(){try{return Date.prototype.toJSON&&new Date(NaN).toJSON()===null&&new Date(Rr).toJSON().indexOf(Fr)!==-1&&Date.prototype.toJSON.call({toISOString:function(){return true}})}catch(r){return false}}();if(!$r){Date.prototype.toJSON=function toJSON(r){var t=e(this);var n=$.ToPrimitive(t);if(typeof n==="number"&&!isFinite(n)){return null}var i=t.toISOString;if(!b(i)){throw new TypeError("toISOString property is not callable")}return i.call(t)}}var Cr=Date.parse("+033658-09-27T01:46:40.000Z")===1e15;var Zr=!isNaN(Date.parse("2012-04-04T24:00:00.500Z"))||!isNaN(Date.parse("2012-11-31T23:59:59.000Z"))||!isNaN(Date.parse("2012-12-31T23:59:60.000Z"));var Jr=isNaN(Date.parse("2000-01-01T00:00:00.000Z"));if(Jr||Zr||!Cr){var zr=Math.pow(2,31)-1;var Br=P(new Date(1970,0,1,0,0,0,zr+1).getTime());Date=function(r){var t=function Date(e,n,i,o,u,f,l){var s=arguments.length;var c;if(this instanceof r){var v=f;var p=l;if(Br&&s>=7&&l>zr){var h=Math.floor(l/zr)*zr;var g=Math.floor(h/1e3);v+=g;p-=g*1e3}c=s===1&&a(e)===e?new r(t.parse(e)):s>=7?new r(e,n,i,o,u,v,p):s>=6?new r(e,n,i,o,u,v):s>=5?new r(e,n,i,o,u):s>=4?new r(e,n,i,o):s>=3?new r(e,n,i):s>=2?new r(e,n):s>=1?new r(e):new r}else{c=r.apply(this,arguments)}if(!A(c)){F(c,{constructor:t},true)}return c};var e=new RegExp("^"+"(\\d{4}|[+-]\\d{6})"+"(?:-(\\d{2})"+"(?:-(\\d{2})"+"(?:"+"T(\\d{2})"+":(\\d{2})"+"(?:"+":(\\d{2})"+"(?:(\\.\\d{1,}))?"+")?"+"("+"Z|"+"(?:"+"([-+])"+"(\\d{2})"+":(\\d{2})"+")"+")?)?)?)?"+"$");var n=[0,31,59,90,120,151,181,212,243,273,304,334,365];var i=function dayFromMonth(r,t){var e=t>1?1:0;return n[t]+Math.floor((r-1969+e)/4)-Math.floor((r-1901+e)/100)+Math.floor((r-1601+e)/400)+365*(r-1970)};var o=function toUTC(t){var e=0;var n=t;if(Br&&n>zr){var i=Math.floor(n/zr)*zr;var a=Math.floor(i/1e3);e+=a;n-=a*1e3}return u(new r(1970,0,1,0,0,e,n))};for(var f in r){if(Z(r,f)){t[f]=r[f]}}F(t,{now:r.now,UTC:r.UTC},true);t.prototype=r.prototype;F(t.prototype,{constructor:t},true);var l=function parse(t){var n=e.exec(t);if(n){var a=u(n[1]),f=u(n[2]||1)-1,l=u(n[3]||1)-1,s=u(n[4]||0),c=u(n[5]||0),v=u(n[6]||0),p=Math.floor(u(n[7]||0)*1e3),h=Boolean(n[4]&&!n[8]),g=n[9]==="-"?1:-1,y=u(n[10]||0),d=u(n[11]||0),m;var w=c>0||v>0||p>0;if(s<(w?24:25)&&c<60&&v<60&&p<1e3&&f>-1&&f<12&&y<24&&d<60&&l>-1&&l=0){e+=Hr.data[t];Hr.data[t]=Math.floor(e/r);e=e%r*Hr.base}},numToString:function numToString(){var r=Hr.size;var t="";while(--r>=0){if(t!==""||r===0||Hr.data[r]!==0){var e=a(Hr.data[r]);if(t===""){t=e}else{t+=G("0000000",0,7-e.length)+e}}}return t},pow:function pow(r,t,e){return t===0?e:t%2===1?pow(r,t-1,e*r):pow(r*r,t/2,e)},log:function log(r){var t=0;var e=r;while(e>=4096){t+=12;e/=4096}while(e>=2){t+=1;e/=2}return t}};var Lr=function toFixed(r){var t,e,n,i,o,f,l,s;t=u(r);t=P(t)?0:Math.floor(t);if(t<0||t>20){throw new RangeError("Number.toFixed called with invalid number of decimals")}e=u(this);if(P(e)){return"NaN"}if(e<=-1e21||e>=1e21){return a(e)}n="";if(e<0){n="-";e=-e}i="0";if(e>1e-21){o=Hr.log(e*Hr.pow(2,69,1))-69;f=o<0?e*Hr.pow(2,-o,1):e/Hr.pow(2,o,1);f*=4503599627370496;o=52-o;if(o>0){Hr.multiply(0,f);l=t;while(l>=7){Hr.multiply(1e7,0);l-=7}Hr.multiply(Hr.pow(10,l,1),0);l=o-1;while(l>=23){Hr.divide(1<<23);l-=23}Hr.divide(1<0){s=i.length;if(s<=t){i=n+G("0.0000000000000000000",0,t-s+2)+i}else{i=n+G(i,0,s-t)+"."+G(i,s-t)}}else{i=n+i}return i};F(f,{toFixed:Lr},Gr);var Xr=function(){try{return 1..toPrecision(undefined)==="1"}catch(r){return true}}();var Yr=f.toPrecision;F(f,{toPrecision:function toPrecision(r){return typeof r==="undefined"?Yr.call(this):Yr.call(this,r)}},Xr);if("ab".split(/(?:ab)*/).length!==2||".".split(/(.?)(.?)/).length!==4||"tesst".split(/(s)*/)[1]==="t"||"test".split(/(?:)/,-1).length!==4||"".split(/.?/).length||".".split(/()()/).length>1){(function(){var r=typeof/()??/.exec("")[1]==="undefined";var t=Math.pow(2,32)-1;o.split=function(e,n){var i=String(this);if(typeof e==="undefined"&&n===0){return[]}if(!E(e)){return H(this,e,n)}var a=[];var o=(e.ignoreCase?"i":"")+(e.multiline?"m":"")+(e.unicode?"u":"")+(e.sticky?"y":""),u=0,f,l,s,v;var p=new RegExp(e.source,o+"g");if(!r){f=new RegExp("^"+p.source+"$(?!\\s)",o)}var h=typeof n==="undefined"?t:$.ToUint32(n);l=p.exec(i);while(l){s=l.index+l[0].length;if(s>u){X(a,G(i,u,l.index));if(!r&&l.length>1){l[0].replace(f,function(){for(var r=1;r1&&l.index=h){break}}if(p.lastIndex===l.index){p.lastIndex++}l=p.exec(i)}if(u===i.length){if(v||!p.test("")){X(a,"")}}else{X(a,G(i,u))}return a.length>h?G(a,0,h):a}})()}else if("0".split(void 0,0).length){o.split=function split(r,t){if(typeof r==="undefined"&&t===0){return[]}return H(this,r,t)}}var qr=o.replace;var Kr=function(){var r=[];"x".replace(/x(.)?/g,function(t,e){X(r,e)});return r.length===1&&typeof r[0]==="undefined"}();if(!Kr){o.replace=function replace(r,t){var e=b(t);var n=E(r)&&/\)[*?]/.test(r.source);if(!e||!n){return qr.call(this,r,t)}else{var i=function(e){var n=arguments.length;var i=r.lastIndex;r.lastIndex=0;var a=r.exec(e)||[];r.lastIndex=i;X(a,arguments[n-2],arguments[n-1]);return t.apply(this,a)};return qr.call(this,r,i)}}}var Qr=o.substr;var Vr="".substr&&"0b".substr(-1)!=="b";F(o,{substr:function substr(r,t){var e=r;if(r<0){e=y(this.length+r,0)}return Qr.call(this,e,t)}},Vr);var Wr=" \n\x0B\f\r \xa0\u1680\u180e\u2000\u2001\u2002\u2003"+"\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028"+"\u2029\ufeff";var _r="\u200b";var rt="["+Wr+"]";var tt=new RegExp("^"+rt+rt+"*");var et=new RegExp(rt+rt+"*$");var nt=o.trim&&(Wr.trim()||!_r.trim());F(o,{trim:function trim(){if(typeof this==="undefined"||this===null){throw new TypeError("can't convert "+this+" to object")}return a(this).replace(tt,"").replace(et,"")}},nt);var it=o.lastIndexOf&&"abc\u3042\u3044".lastIndexOf("\u3042\u3044",2)!==-1;F(o,{lastIndexOf:function lastIndexOf(r){if(typeof this==="undefined"||this===null){throw new TypeError("can't convert "+this+" to object")}var t=a(this);var e=a(r);var n=arguments.length>1?u(arguments[1]):NaN;var i=P(n)?Infinity:$.ToInteger(n);var o=d(y(i,0),t.length);var f=e.length;var l=o+f;while(l>0){l=y(0,l-f);var s=L(G(t,l,o+f),e);if(s!==-1){return l+s}}return-1}},it);var at=o.lastIndexOf;F(o,{lastIndexOf:function lastIndexOf(r){return at.apply(this,arguments)}},o.lastIndexOf.length!==1);if(parseInt(Wr+"08")!==8||parseInt(Wr+"0x16")!==22){parseInt=function(r){var t=/^[\-+]?0[xX]/;return function parseInt(e,n){var i=a(e).trim();var o=u(n)||(t.test(i)?16:10);return r(i,o)}}(parseInt)}if(String(new RangeError("test"))!=="RangeError: test"){var ot=function toString(){if(typeof this==="undefined"||this===null){throw new TypeError("can't convert "+this+" to object")}var r=this.name;if(typeof r==="undefined"){r="Error"}else if(typeof r!=="string"){r=a(r)}var t=this.message;if(typeof t==="undefined"){t=""}else if(typeof t!=="string"){t=a(t)}if(!r){return t}if(!t){return r}return r+": "+t};Error.prototype.toString=ot}if(R){var ut=function(r,t){if(Y(r,t)){var e=Object.getOwnPropertyDescriptor(r,t);e.enumerable=false;Object.defineProperty(r,t,e)}};ut(Error.prototype,"message");if(Error.prototype.message!==""){Error.prototype.message=""}ut(Error.prototype,"name")}if(String(/a/gim)!=="/a/gim"){var ft=function toString(){var r="/"+this.source+"/";if(this.global){r+="g"}if(this.ignoreCase){r+="i"}if(this.multiline){r+="m"}return r};RegExp.prototype.toString=ft}}); //# sourceMappingURL=es5-shim.map es5-shim-4.4.1/package.json000066400000000000000000000045501263422513500154470ustar00rootroot00000000000000{ "name": "es5-shim", "version": "4.4.1", "description": "ECMAScript 5 compatibility shims for legacy JavaScript engines", "homepage": "http://github.com/es-shims/es5-shim/", "contributors": [ "Kris Kowal (http://github.com/kriskowal/)", "Sami Samhuri (http://samhuri.net/)", "Florian Schäfer (http://github.com/fschaefer)", "Irakli Gozalishvili (http://jeditoolkit.com)", "Kit Cambridge (http://kitcambridge.github.com)", "Jordan Harband (https://github.com/ljharb/)" ], "bugs": { "mail": "ljharb@gmail.com", "url": "http://github.com/es-shims/es5-shim/issues" }, "license": "MIT", "main": "es5-shim.js", "repository": { "type": "git", "url": "http://github.com/es-shims/es5-shim.git" }, "scripts": { "minify": "npm run minify-shim && npm run minify-sham", "minify-shim": "uglifyjs es5-shim.js --keep-fnames --comments --source-map=es5-shim.map -m -b ascii_only=true,beautify=false > es5-shim.min.js", "minify-sham": "uglifyjs es5-sham.js --keep-fnames --comments --source-map=es5-sham.map -m -b ascii_only=true,beautify=false > es5-sham.min.js", "test": "npm run lint && npm run tests-only", "tests-only": "jasmine-node --matchall ./ tests/spec/", "test-native": "jasmine-node --matchall tests/spec/", "lint": "npm run jscs && npm run eslint", "eslint": "eslint tests/helpers/*.js tests/spec/*.js es5-shim.js es5-sham.js", "jscs": "jscs tests/helpers/*.js tests/spec/*.js es5-shim.js es5-sham.js" }, "devDependencies": { "eslint": "^1.10.1", "@ljharb/eslint-config": "^1.6.0", "jasmine-node": "^1.14.5", "jscs": "^2.6.0", "uglify-js": "^2.6.1", "replace": "^0.3.0", "semver": "^5.1.0" }, "engines": { "node": ">=0.4.0" }, "testling": { "browsers": [ "iexplore/6.0..latest", "firefox/3.0..6.0", "firefox/18.0..latest", "firefox/nightly", "chrome/4.0..10.0", "chrome/25.0..latest", "chrome/canary", "opera/10.0..latest", "opera/next", "safari/4.0..latest", "ipad/6.0..latest", "iphone/6.0..latest", "android-browser/4.2" ] }, "keywords": [ "shim", "es5", "es5 shim", "javascript", "ecmascript", "polyfill" ] } es5-shim-4.4.1/shims.json000066400000000000000000000001221263422513500151660ustar00rootroot00000000000000{ "Object": { "prototype": {}, "keys": "object-keys" } } es5-shim-4.4.1/tests/000077500000000000000000000000001263422513500143175ustar00rootroot00000000000000es5-shim-4.4.1/tests/helpers/000077500000000000000000000000001263422513500157615ustar00rootroot00000000000000es5-shim-4.4.1/tests/helpers/h-matchers.js000066400000000000000000000015261263422513500203560ustar00rootroot00000000000000/* global beforeEach, expect */ var has = Object.prototype.hasOwnProperty; var getKeys = function (o) { 'use strict'; var key, a = []; for (key in o) { if (has.call(o, key)) { a.push(key); } } return a; }; beforeEach(function () { 'use strict'; this.addMatchers({ toExactlyMatch: function (expected) { var a1, a2, l, i, key; var actual = this.actual; a1 = getKeys(actual); a2 = getKeys(expected); l = a1.length; if (l !== a2.length) { return false; } for (i = 0; i < l; i++) { key = a1[i]; expect(key).toEqual(a2[i]); expect(actual[key]).toEqual(expected[key]); } return true; } }); }); es5-shim-4.4.1/tests/index.html000066400000000000000000000031641263422513500163200ustar00rootroot00000000000000 Jasmine Spec Runner es5-shim-4.4.1/tests/index.min.html000066400000000000000000000030141263422513500170740ustar00rootroot00000000000000 Jasmine Spec Runner es5-shim-4.4.1/tests/lib/000077500000000000000000000000001263422513500150655ustar00rootroot00000000000000es5-shim-4.4.1/tests/lib/jasmine-html.js000066400000000000000000000154261263422513500200230ustar00rootroot00000000000000jasmine.TrivialReporter = function(doc) { this.document = doc || document; this.suiteDivs = {}; this.logRunningSpecs = false; }; jasmine.TrivialReporter.prototype.createDom = function(type, attrs, childrenVarArgs) { var el = document.createElement(type); for (var i = 2; i < arguments.length; i++) { var child = arguments[i]; if (typeof child === 'string') { el.appendChild(document.createTextNode(child)); } else { if (child) { el.appendChild(child); } } } for (var attr in attrs) { if (attr == "className") { el[attr] = attrs[attr]; } else { el.setAttribute(attr, attrs[attr]); } } return el; }; jasmine.TrivialReporter.prototype.reportRunnerStarting = function(runner) { var showPassed, showSkipped; this.outerDiv = this.createDom('div', { className: 'jasmine_reporter' }, this.createDom('div', { className: 'banner' }, this.createDom('div', { className: 'logo' }, this.createDom('span', { className: 'title' }, "Jasmine"), this.createDom('span', { className: 'version' }, runner.env.versionString())), this.createDom('div', { className: 'options' }, "Show ", showPassed = this.createDom('input', { id: "__jasmine_TrivialReporter_showPassed__", type: 'checkbox' }), this.createDom('label', { "for": "__jasmine_TrivialReporter_showPassed__" }, " passed "), showSkipped = this.createDom('input', { id: "__jasmine_TrivialReporter_showSkipped__", type: 'checkbox' }), this.createDom('label', { "for": "__jasmine_TrivialReporter_showSkipped__" }, " skipped") ) ), this.runnerDiv = this.createDom('div', { className: 'runner running' }, this.createDom('a', { className: 'run_spec', href: '?' }, "run all"), this.runnerMessageSpan = this.createDom('span', {}, "Running..."), this.finishedAtSpan = this.createDom('span', { className: 'finished-at' }, "")) ); this.document.body.appendChild(this.outerDiv); var suites = runner.suites(); for (var i = 0; i < suites.length; i++) { var suite = suites[i]; var suiteDiv = this.createDom('div', { className: 'suite' }, this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, "run"), this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(suite.getFullName()) }, suite.description)); this.suiteDivs[suite.id] = suiteDiv; var parentDiv = this.outerDiv; if (suite.parentSuite) { parentDiv = this.suiteDivs[suite.parentSuite.id]; } parentDiv.appendChild(suiteDiv); } this.startedAt = new Date(); var self = this; showPassed.onclick = function(evt) { if (showPassed.checked) { self.outerDiv.className += ' show-passed'; } else { self.outerDiv.className = self.outerDiv.className.replace(/ show-passed/, ''); } }; showSkipped.onclick = function(evt) { if (showSkipped.checked) { self.outerDiv.className += ' show-skipped'; } else { self.outerDiv.className = self.outerDiv.className.replace(/ show-skipped/, ''); } }; }; jasmine.TrivialReporter.prototype.reportRunnerResults = function(runner) { var results = runner.results(); var className = (results.failedCount > 0) ? "runner failed" : "runner passed"; this.runnerDiv.setAttribute("class", className); //do it twice for IE this.runnerDiv.setAttribute("className", className); var specs = runner.specs(); var specCount = 0; for (var i = 0; i < specs.length; i++) { if (this.specFilter(specs[i])) { specCount++; } } var message = "" + specCount + " spec" + (specCount == 1 ? "" : "s" ) + ", " + results.failedCount + " failure" + ((results.failedCount == 1) ? "" : "s"); message += " in " + ((new Date().getTime() - this.startedAt.getTime()) / 1000) + "s"; this.runnerMessageSpan.replaceChild(this.createDom('a', { className: 'description', href: '?'}, message), this.runnerMessageSpan.firstChild); this.finishedAtSpan.appendChild(document.createTextNode("Finished at " + new Date().toString())); }; jasmine.TrivialReporter.prototype.reportSuiteResults = function(suite) { var results = suite.results(); var status = results.passed() ? 'passed' : 'failed'; if (results.totalCount === 0) { // todo: change this to check results.skipped status = 'skipped'; } this.suiteDivs[suite.id].className += " " + status; }; jasmine.TrivialReporter.prototype.reportSpecStarting = function(spec) { if (this.logRunningSpecs) { this.log('>> Jasmine Running ' + spec.suite.description + ' ' + spec.description + '...'); } }; jasmine.TrivialReporter.prototype.reportSpecResults = function(spec) { var results = spec.results(); var status = results.passed() ? 'passed' : 'failed'; if (results.skipped) { status = 'skipped'; } var specDiv = this.createDom('div', { className: 'spec ' + status }, this.createDom('a', { className: 'run_spec', href: '?spec=' + encodeURIComponent(spec.getFullName()) }, "run"), this.createDom('a', { className: 'description', href: '?spec=' + encodeURIComponent(spec.getFullName()), title: spec.getFullName() }, spec.description)); var resultItems = results.getItems(); var messagesDiv = this.createDom('div', { className: 'messages' }); for (var i = 0; i < resultItems.length; i++) { var result = resultItems[i]; if (result.type == 'log') { messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage log'}, result.toString())); } else if (result.type == 'expect' && result.passed && !result.passed()) { messagesDiv.appendChild(this.createDom('div', {className: 'resultMessage fail'}, result.message)); if (result.trace.stack) { messagesDiv.appendChild(this.createDom('div', {className: 'stackTrace'}, result.trace.stack)); } } } if (messagesDiv.childNodes.length > 0) { specDiv.appendChild(messagesDiv); } this.suiteDivs[spec.suite.id].appendChild(specDiv); }; jasmine.TrivialReporter.prototype.log = function() { var console = jasmine.getGlobal().console; if (console && console.log) { if (console.log.apply) { console.log.apply(console, arguments); } else { console.log(arguments); // ie fix: console.log.apply doesn't exist on ie } } }; jasmine.TrivialReporter.prototype.getLocation = function() { return this.document.location; }; jasmine.TrivialReporter.prototype.specFilter = function(spec) { var paramMap = {}; var params = this.getLocation().search.substring(1).split('&'); for (var i = 0; i < params.length; i++) { var p = params[i].split('='); paramMap[decodeURIComponent(p[0])] = decodeURIComponent(p[1]); } if (!paramMap.spec) { return true; } return spec.getFullName().indexOf(paramMap.spec) === 0; }; es5-shim-4.4.1/tests/lib/jasmine.css000066400000000000000000000041101263422513500172210ustar00rootroot00000000000000body { font-family: "Helvetica Neue Light", "Lucida Grande", "Calibri", "Arial", sans-serif; } .jasmine_reporter a:visited, .jasmine_reporter a { color: #303; } .jasmine_reporter a:hover, .jasmine_reporter a:active { color: blue; } .run_spec { float:right; padding-right: 5px; font-size: .8em; text-decoration: none; } .jasmine_reporter { margin: 0 5px; } .banner { color: #303; background-color: #fef; padding: 5px; } .logo { float: left; font-size: 1.1em; padding-left: 5px; } .logo .version { font-size: .6em; padding-left: 1em; } .runner.running { background-color: yellow; } .options { text-align: right; font-size: .8em; } .suite { border: 1px outset gray; margin: 5px 0; padding-left: 1em; } .suite .suite { margin: 5px; } .suite.passed { background-color: #dfd; } .suite.failed { background-color: #fdd; } .spec { margin: 5px; padding-left: 1em; clear: both; } .spec.failed, .spec.passed, .spec.skipped { padding-bottom: 5px; border: 1px solid gray; } .spec.failed { background-color: #fbb; border-color: red; } .spec.passed { background-color: #bfb; border-color: green; } .spec.skipped { background-color: #bbb; } .messages { border-left: 1px dashed gray; padding-left: 1em; padding-right: 1em; } .passed { background-color: #cfc; display: none; } .failed { background-color: #fbb; } .skipped { color: #777; background-color: #eee; display: none; } /*.resultMessage {*/ /*white-space: pre;*/ /*}*/ .resultMessage span.result { display: block; line-height: 2em; color: black; } .resultMessage .mismatch { color: black; } .stackTrace { white-space: pre; font-size: .8em; margin-left: 10px; max-height: 5em; overflow: auto; border: 1px inset red; padding: 1em; background: #eef; } .finished-at { padding-left: 1em; font-size: .6em; } .show-passed .passed, .show-skipped .skipped { display: block; } #jasmine_content { position:fixed; right: 100%; } .runner { border: 1px solid gray; display: block; margin: 5px 0; padding: 2px 0 2px 10px; } es5-shim-4.4.1/tests/lib/jasmine.js000066400000000000000000002123411263422513500170540ustar00rootroot00000000000000var isCommonJS = typeof window == "undefined" && typeof exports == "object"; /** * Top level namespace for Jasmine, a lightweight JavaScript BDD/spec/testing framework. * * @namespace */ var jasmine = {}; if (isCommonJS) exports.jasmine = jasmine; /** * @private */ jasmine.unimplementedMethod_ = function() { throw new Error("unimplemented method"); }; /** * Use jasmine.undefined instead of undefined, since undefined is just * a plain old variable and may be redefined by somebody else. * * @private */ jasmine.undefined = jasmine.___undefined___; /** * Show diagnostic messages in the console if set to true * */ jasmine.VERBOSE = false; /** * Default interval in milliseconds for event loop yields (e.g. to allow network activity or to refresh the screen with the HTML-based runner). Small values here may result in slow test running. Zero means no updates until all tests have completed. * */ jasmine.DEFAULT_UPDATE_INTERVAL = 250; /** * Maximum levels of nesting that will be included when an object is pretty-printed */ jasmine.MAX_PRETTY_PRINT_DEPTH = 40; /** * Default timeout interval in milliseconds for waitsFor() blocks. */ jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; /** * By default exceptions thrown in the context of a test are caught by jasmine so that it can run the remaining tests in the suite. * Set to false to let the exception bubble up in the browser. * */ jasmine.CATCH_EXCEPTIONS = true; jasmine.getGlobal = function() { function getGlobal() { return this; } return getGlobal(); }; /** * Allows for bound functions to be compared. Internal use only. * * @ignore * @private * @param base {Object} bound 'this' for the function * @param name {Function} function to find */ jasmine.bindOriginal_ = function(base, name) { var original = base[name]; if (original.apply) { return function() { return original.apply(base, arguments); }; } else { // IE support return jasmine.getGlobal()[name]; } }; jasmine.setTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'setTimeout'); jasmine.clearTimeout = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearTimeout'); jasmine.setInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'setInterval'); jasmine.clearInterval = jasmine.bindOriginal_(jasmine.getGlobal(), 'clearInterval'); jasmine.MessageResult = function(values) { this.type = 'log'; this.values = values; this.trace = new Error(); // todo: test better }; jasmine.MessageResult.prototype.toString = function() { var text = ""; for (var i = 0; i < this.values.length; i++) { if (i > 0) text += " "; if (jasmine.isString_(this.values[i])) { text += this.values[i]; } else { text += jasmine.pp(this.values[i]); } } return text; }; jasmine.ExpectationResult = function(params) { this.type = 'expect'; this.matcherName = params.matcherName; this.passed_ = params.passed; this.expected = params.expected; this.actual = params.actual; this.message = this.passed_ ? 'Passed.' : params.message; var trace = (params.trace || new Error(this.message)); this.trace = this.passed_ ? '' : trace; }; jasmine.ExpectationResult.prototype.toString = function () { return this.message; }; jasmine.ExpectationResult.prototype.passed = function () { return this.passed_; }; /** * Getter for the Jasmine environment. Ensures one gets created */ jasmine.getEnv = function() { var env = jasmine.currentEnv_ = jasmine.currentEnv_ || new jasmine.Env(); return env; }; /** * @ignore * @private * @param value * @returns {Boolean} */ jasmine.isArray_ = function(value) { return jasmine.isA_("Array", value); }; /** * @ignore * @private * @param value * @returns {Boolean} */ jasmine.isString_ = function(value) { return jasmine.isA_("String", value); }; /** * @ignore * @private * @param value * @returns {Boolean} */ jasmine.isNumber_ = function(value) { return jasmine.isA_("Number", value); }; /** * @ignore * @private * @param {String} typeName * @param value * @returns {Boolean} */ jasmine.isA_ = function(typeName, value) { return Object.prototype.toString.apply(value) === '[object ' + typeName + ']'; }; /** * Pretty printer for expecations. Takes any object and turns it into a human-readable string. * * @param value {Object} an object to be outputted * @returns {String} */ jasmine.pp = function(value) { var stringPrettyPrinter = new jasmine.StringPrettyPrinter(); stringPrettyPrinter.format(value); return stringPrettyPrinter.string; }; /** * Returns true if the object is a DOM Node. * * @param {Object} obj object to check * @returns {Boolean} */ jasmine.isDomNode = function(obj) { return obj.nodeType > 0; }; /** * Returns a matchable 'generic' object of the class type. For use in expecations of type when values don't matter. * * @example * // don't care about which function is passed in, as long as it's a function * expect(mySpy).toHaveBeenCalledWith(jasmine.any(Function)); * * @param {Class} clazz * @returns matchable object of the type clazz */ jasmine.any = function(clazz) { return new jasmine.Matchers.Any(clazz); }; /** * Returns a matchable subset of a JSON object. For use in expectations when you don't care about all of the * attributes on the object. * * @example * // don't care about any other attributes than foo. * expect(mySpy).toHaveBeenCalledWith(jasmine.objectContaining({foo: "bar"}); * * @param sample {Object} sample * @returns matchable object for the sample */ jasmine.objectContaining = function (sample) { return new jasmine.Matchers.ObjectContaining(sample); }; /** * Jasmine Spies are test doubles that can act as stubs, spies, fakes or when used in an expecation, mocks. * * Spies should be created in test setup, before expectations. They can then be checked, using the standard Jasmine * expectation syntax. Spies can be checked if they were called or not and what the calling params were. * * A Spy has the following fields: wasCalled, callCount, mostRecentCall, and argsForCall (see docs). * * Spies are torn down at the end of every spec. * * Note: Do not call new jasmine.Spy() directly - a spy must be created using spyOn, jasmine.createSpy or jasmine.createSpyObj. * * @example * // a stub * var myStub = jasmine.createSpy('myStub'); // can be used anywhere * * // spy example * var foo = { * not: function(bool) { return !bool; } * } * * // actual foo.not will not be called, execution stops * spyOn(foo, 'not'); // foo.not spied upon, execution will continue to implementation * spyOn(foo, 'not').andCallThrough(); * * // fake example * var foo = { * not: function(bool) { return !bool; } * } * * // foo.not(val) will return val * spyOn(foo, 'not').andCallFake(function(value) {return value;}); * * // mock example * foo.not(7 == 7); * expect(foo.not).toHaveBeenCalled(); * expect(foo.not).toHaveBeenCalledWith(true); * * @constructor * @see spyOn, jasmine.createSpy, jasmine.createSpyObj * @param {String} name */ jasmine.Spy = function(name) { /** * The name of the spy, if provided. */ this.identity = name || 'unknown'; /** * Is this Object a spy? */ this.isSpy = true; /** * The actual function this spy stubs. */ this.plan = function() { }; /** * Tracking of the most recent call to the spy. * @example * var mySpy = jasmine.createSpy('foo'); * mySpy(1, 2); * mySpy.mostRecentCall.args = [1, 2]; */ this.mostRecentCall = {}; /** * Holds arguments for each call to the spy, indexed by call count * @example * var mySpy = jasmine.createSpy('foo'); * mySpy(1, 2); * mySpy(7, 8); * mySpy.mostRecentCall.args = [7, 8]; * mySpy.argsForCall[0] = [1, 2]; * mySpy.argsForCall[1] = [7, 8]; */ this.argsForCall = []; this.calls = []; }; /** * Tells a spy to call through to the actual implemenatation. * * @example * var foo = { * bar: function() { // do some stuff } * } * * // defining a spy on an existing property: foo.bar * spyOn(foo, 'bar').andCallThrough(); */ jasmine.Spy.prototype.andCallThrough = function() { this.plan = this.originalValue; return this; }; /** * For setting the return value of a spy. * * @example * // defining a spy from scratch: foo() returns 'baz' * var foo = jasmine.createSpy('spy on foo').andReturn('baz'); * * // defining a spy on an existing property: foo.bar() returns 'baz' * spyOn(foo, 'bar').andReturn('baz'); * * @param {Object} value */ jasmine.Spy.prototype.andReturn = function(value) { this.plan = function() { return value; }; return this; }; /** * For throwing an exception when a spy is called. * * @example * // defining a spy from scratch: foo() throws an exception w/ message 'ouch' * var foo = jasmine.createSpy('spy on foo').andThrow('baz'); * * // defining a spy on an existing property: foo.bar() throws an exception w/ message 'ouch' * spyOn(foo, 'bar').andThrow('baz'); * * @param {String} exceptionMsg */ jasmine.Spy.prototype.andThrow = function(exceptionMsg) { this.plan = function() { throw exceptionMsg; }; return this; }; /** * Calls an alternate implementation when a spy is called. * * @example * var baz = function() { * // do some stuff, return something * } * // defining a spy from scratch: foo() calls the function baz * var foo = jasmine.createSpy('spy on foo').andCall(baz); * * // defining a spy on an existing property: foo.bar() calls an anonymnous function * spyOn(foo, 'bar').andCall(function() { return 'baz';} ); * * @param {Function} fakeFunc */ jasmine.Spy.prototype.andCallFake = function(fakeFunc) { this.plan = fakeFunc; return this; }; /** * Resets all of a spy's the tracking variables so that it can be used again. * * @example * spyOn(foo, 'bar'); * * foo.bar(); * * expect(foo.bar.callCount).toEqual(1); * * foo.bar.reset(); * * expect(foo.bar.callCount).toEqual(0); */ jasmine.Spy.prototype.reset = function() { this.wasCalled = false; this.callCount = 0; this.argsForCall = []; this.calls = []; this.mostRecentCall = {}; }; jasmine.createSpy = function(name) { var spyObj = function() { spyObj.wasCalled = true; spyObj.callCount++; var args = jasmine.util.argsToArray(arguments); spyObj.mostRecentCall.object = this; spyObj.mostRecentCall.args = args; spyObj.argsForCall.push(args); spyObj.calls.push({object: this, args: args}); return spyObj.plan.apply(this, arguments); }; var spy = new jasmine.Spy(name); for (var prop in spy) { spyObj[prop] = spy[prop]; } spyObj.reset(); return spyObj; }; /** * Determines whether an object is a spy. * * @param {jasmine.Spy|Object} putativeSpy * @returns {Boolean} */ jasmine.isSpy = function(putativeSpy) { return putativeSpy && putativeSpy.isSpy; }; /** * Creates a more complicated spy: an Object that has every property a function that is a spy. Used for stubbing something * large in one call. * * @param {String} baseName name of spy class * @param {Array} methodNames array of names of methods to make spies */ jasmine.createSpyObj = function(baseName, methodNames) { if (!jasmine.isArray_(methodNames) || methodNames.length === 0) { throw new Error('createSpyObj requires a non-empty array of method names to create spies for'); } var obj = {}; for (var i = 0; i < methodNames.length; i++) { obj[methodNames[i]] = jasmine.createSpy(baseName + '.' + methodNames[i]); } return obj; }; /** * All parameters are pretty-printed and concatenated together, then written to the current spec's output. * * Be careful not to leave calls to jasmine.log in production code. */ jasmine.log = function() { var spec = jasmine.getEnv().currentSpec; spec.log.apply(spec, arguments); }; /** * Function that installs a spy on an existing object's method name. Used within a Spec to create a spy. * * @example * // spy example * var foo = { * not: function(bool) { return !bool; } * } * spyOn(foo, 'not'); // actual foo.not will not be called, execution stops * * @see jasmine.createSpy * @param obj * @param methodName * @return {jasmine.Spy} a Jasmine spy that can be chained with all spy methods */ var spyOn = function(obj, methodName) { return jasmine.getEnv().currentSpec.spyOn(obj, methodName); }; if (isCommonJS) exports.spyOn = spyOn; /** * Creates a Jasmine spec that will be added to the current suite. * * // TODO: pending tests * * @example * it('should be true', function() { * expect(true).toEqual(true); * }); * * @param {String} desc description of this specification * @param {Function} func defines the preconditions and expectations of the spec */ var it = function(desc, func) { return jasmine.getEnv().it(desc, func); }; if (isCommonJS) exports.it = it; /** * Creates a disabled Jasmine spec. * * A convenience method that allows existing specs to be disabled temporarily during development. * * @param {String} desc description of this specification * @param {Function} func defines the preconditions and expectations of the spec */ var xit = function(desc, func) { return jasmine.getEnv().xit(desc, func); }; if (isCommonJS) exports.xit = xit; /** * Starts a chain for a Jasmine expectation. * * It is passed an Object that is the actual value and should chain to one of the many * jasmine.Matchers functions. * * @param {Object} actual Actual value to test against and expected value * @return {jasmine.Matchers} */ var expect = function(actual) { return jasmine.getEnv().currentSpec.expect(actual); }; if (isCommonJS) exports.expect = expect; /** * Defines part of a jasmine spec. Used in cominbination with waits or waitsFor in asynchrnous specs. * * @param {Function} func Function that defines part of a jasmine spec. */ var runs = function(func) { jasmine.getEnv().currentSpec.runs(func); }; if (isCommonJS) exports.runs = runs; /** * Waits a fixed time period before moving to the next block. * * @deprecated Use waitsFor() instead * @param {Number} timeout milliseconds to wait */ var waits = function(timeout) { jasmine.getEnv().currentSpec.waits(timeout); }; if (isCommonJS) exports.waits = waits; /** * Waits for the latchFunction to return true before proceeding to the next block. * * @param {Function} latchFunction * @param {String} optional_timeoutMessage * @param {Number} optional_timeout */ var waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { jasmine.getEnv().currentSpec.waitsFor.apply(jasmine.getEnv().currentSpec, arguments); }; if (isCommonJS) exports.waitsFor = waitsFor; /** * A function that is called before each spec in a suite. * * Used for spec setup, including validating assumptions. * * @param {Function} beforeEachFunction */ var beforeEach = function(beforeEachFunction) { jasmine.getEnv().beforeEach(beforeEachFunction); }; if (isCommonJS) exports.beforeEach = beforeEach; /** * A function that is called after each spec in a suite. * * Used for restoring any state that is hijacked during spec execution. * * @param {Function} afterEachFunction */ var afterEach = function(afterEachFunction) { jasmine.getEnv().afterEach(afterEachFunction); }; if (isCommonJS) exports.afterEach = afterEach; /** * Defines a suite of specifications. * * Stores the description and all defined specs in the Jasmine environment as one suite of specs. Variables declared * are accessible by calls to beforeEach, it, and afterEach. Describe blocks can be nested, allowing for specialization * of setup in some tests. * * @example * // TODO: a simple suite * * // TODO: a simple suite with a nested describe block * * @param {String} description A string, usually the class under test. * @param {Function} specDefinitions function that defines several specs. */ var describe = function(description, specDefinitions) { return jasmine.getEnv().describe(description, specDefinitions); }; if (isCommonJS) exports.describe = describe; /** * Disables a suite of specifications. Used to disable some suites in a file, or files, temporarily during development. * * @param {String} description A string, usually the class under test. * @param {Function} specDefinitions function that defines several specs. */ var xdescribe = function(description, specDefinitions) { return jasmine.getEnv().xdescribe(description, specDefinitions); }; if (isCommonJS) exports.xdescribe = xdescribe; // Provide the XMLHttpRequest class for IE 5.x-6.x: jasmine.XmlHttpRequest = (typeof XMLHttpRequest == "undefined") ? function() { function tryIt(f) { try { return f(); } catch(e) { } return null; } var xhr = tryIt(function() { return new ActiveXObject("Msxml2.XMLHTTP.6.0"); }) || tryIt(function() { return new ActiveXObject("Msxml2.XMLHTTP.3.0"); }) || tryIt(function() { return new ActiveXObject("Msxml2.XMLHTTP"); }) || tryIt(function() { return new ActiveXObject("Microsoft.XMLHTTP"); }); if (!xhr) throw new Error("This browser does not support XMLHttpRequest."); return xhr; } : XMLHttpRequest; /** * @namespace */ jasmine.util = {}; /** * Declare that a child class inherit it's prototype from the parent class. * * @private * @param {Function} childClass * @param {Function} parentClass */ jasmine.util.inherit = function(childClass, parentClass) { /** * @private */ var subclass = function() { }; subclass.prototype = parentClass.prototype; childClass.prototype = new subclass(); }; jasmine.util.formatException = function(e) { var lineNumber; if (e.line) { lineNumber = e.line; } else if (e.lineNumber) { lineNumber = e.lineNumber; } var file; if (e.sourceURL) { file = e.sourceURL; } else if (e.fileName) { file = e.fileName; } var message = (e.name && e.message) ? (e.name + ': ' + e.message) : e.toString(); if (file && lineNumber) { message += ' in ' + file + ' (line ' + lineNumber + ')'; } return message; }; jasmine.util.htmlEscape = function(str) { if (!str) return str; return str.replace(/&/g, '&') .replace(//g, '>'); }; jasmine.util.argsToArray = function(args) { var arrayOfArgs = []; for (var i = 0; i < args.length; i++) arrayOfArgs.push(args[i]); return arrayOfArgs; }; jasmine.util.extend = function(destination, source) { for (var property in source) destination[property] = source[property]; return destination; }; /** * Environment for Jasmine * * @constructor */ jasmine.Env = function() { this.currentSpec = null; this.currentSuite = null; this.currentRunner_ = new jasmine.Runner(this); this.reporter = new jasmine.MultiReporter(); this.updateInterval = jasmine.DEFAULT_UPDATE_INTERVAL; this.defaultTimeoutInterval = jasmine.DEFAULT_TIMEOUT_INTERVAL; this.lastUpdate = 0; this.specFilter = function() { return true; }; this.nextSpecId_ = 0; this.nextSuiteId_ = 0; this.equalityTesters_ = []; // wrap matchers this.matchersClass = function() { jasmine.Matchers.apply(this, arguments); }; jasmine.util.inherit(this.matchersClass, jasmine.Matchers); jasmine.Matchers.wrapInto_(jasmine.Matchers.prototype, this.matchersClass); }; jasmine.Env.prototype.setTimeout = jasmine.setTimeout; jasmine.Env.prototype.clearTimeout = jasmine.clearTimeout; jasmine.Env.prototype.setInterval = jasmine.setInterval; jasmine.Env.prototype.clearInterval = jasmine.clearInterval; /** * @returns an object containing jasmine version build info, if set. */ jasmine.Env.prototype.version = function () { if (jasmine.version_) { return jasmine.version_; } else { throw new Error('Version not set'); } }; /** * @returns string containing jasmine version build info, if set. */ jasmine.Env.prototype.versionString = function() { if (!jasmine.version_) { return "version unknown"; } var version = this.version(); var versionString = version.major + "." + version.minor + "." + version.build; if (version.release_candidate) { versionString += ".rc" + version.release_candidate; } versionString += " revision " + version.revision; return versionString; }; /** * @returns a sequential integer starting at 0 */ jasmine.Env.prototype.nextSpecId = function () { return this.nextSpecId_++; }; /** * @returns a sequential integer starting at 0 */ jasmine.Env.prototype.nextSuiteId = function () { return this.nextSuiteId_++; }; /** * Register a reporter to receive status updates from Jasmine. * @param {jasmine.Reporter} reporter An object which will receive status updates. */ jasmine.Env.prototype.addReporter = function(reporter) { this.reporter.addReporter(reporter); }; jasmine.Env.prototype.execute = function() { this.currentRunner_.execute(); }; jasmine.Env.prototype.describe = function(description, specDefinitions) { var suite = new jasmine.Suite(this, description, specDefinitions, this.currentSuite); var parentSuite = this.currentSuite; if (parentSuite) { parentSuite.add(suite); } else { this.currentRunner_.add(suite); } this.currentSuite = suite; var declarationError = null; try { specDefinitions.call(suite); } catch(e) { declarationError = e; } if (declarationError) { this.it("encountered a declaration exception", function() { throw declarationError; }); } this.currentSuite = parentSuite; return suite; }; jasmine.Env.prototype.beforeEach = function(beforeEachFunction) { if (this.currentSuite) { this.currentSuite.beforeEach(beforeEachFunction); } else { this.currentRunner_.beforeEach(beforeEachFunction); } }; jasmine.Env.prototype.currentRunner = function () { return this.currentRunner_; }; jasmine.Env.prototype.afterEach = function(afterEachFunction) { if (this.currentSuite) { this.currentSuite.afterEach(afterEachFunction); } else { this.currentRunner_.afterEach(afterEachFunction); } }; jasmine.Env.prototype.xdescribe = function(desc, specDefinitions) { return { execute: function() { } }; }; jasmine.Env.prototype.it = function(description, func) { var spec = new jasmine.Spec(this, this.currentSuite, description); this.currentSuite.add(spec); this.currentSpec = spec; if (func) { spec.runs(func); } return spec; }; jasmine.Env.prototype.xit = function(desc, func) { return { id: this.nextSpecId(), runs: function() { } }; }; jasmine.Env.prototype.compareRegExps_ = function(a, b, mismatchKeys, mismatchValues) { if (a.source != b.source) mismatchValues.push("expected pattern /" + b.source + "/ is not equal to the pattern /" + a.source + "/"); if (a.ignoreCase != b.ignoreCase) mismatchValues.push("expected modifier i was" + (b.ignoreCase ? " " : " not ") + "set and does not equal the origin modifier"); if (a.global != b.global) mismatchValues.push("expected modifier g was" + (b.global ? " " : " not ") + "set and does not equal the origin modifier"); if (a.multiline != b.multiline) mismatchValues.push("expected modifier m was" + (b.multiline ? " " : " not ") + "set and does not equal the origin modifier"); if (a.sticky != b.sticky) mismatchValues.push("expected modifier y was" + (b.sticky ? " " : " not ") + "set and does not equal the origin modifier"); return (mismatchValues.length === 0); }; jasmine.Env.prototype.compareObjects_ = function(a, b, mismatchKeys, mismatchValues) { if (a.__Jasmine_been_here_before__ === b && b.__Jasmine_been_here_before__ === a) { return true; } a.__Jasmine_been_here_before__ = b; b.__Jasmine_been_here_before__ = a; var hasKey = function(obj, keyName) { return obj !== null && obj[keyName] !== jasmine.undefined; }; for (var property in b) { if (!hasKey(a, property) && hasKey(b, property)) { mismatchKeys.push("expected has key '" + property + "', but missing from actual."); } } for (property in a) { if (!hasKey(b, property) && hasKey(a, property)) { mismatchKeys.push("expected missing key '" + property + "', but present in actual."); } } for (property in b) { if (property == '__Jasmine_been_here_before__') continue; if (!this.equals_(a[property], b[property], mismatchKeys, mismatchValues)) { mismatchValues.push("'" + property + "' was '" + (b[property] ? jasmine.util.htmlEscape(b[property].toString()) : b[property]) + "' in expected, but was '" + (a[property] ? jasmine.util.htmlEscape(a[property].toString()) : a[property]) + "' in actual."); } } if (jasmine.isArray_(a) && jasmine.isArray_(b) && a.length != b.length) { mismatchValues.push("arrays were not the same length"); } delete a.__Jasmine_been_here_before__; delete b.__Jasmine_been_here_before__; return (mismatchKeys.length === 0 && mismatchValues.length === 0); }; jasmine.Env.prototype.equals_ = function(a, b, mismatchKeys, mismatchValues) { mismatchKeys = mismatchKeys || []; mismatchValues = mismatchValues || []; for (var i = 0; i < this.equalityTesters_.length; i++) { var equalityTester = this.equalityTesters_[i]; var result = equalityTester(a, b, this, mismatchKeys, mismatchValues); if (result !== jasmine.undefined) return result; } if (a === b) return true; if (a === jasmine.undefined || a === null || b === jasmine.undefined || b === null) { return (a == jasmine.undefined && b == jasmine.undefined); } if (jasmine.isDomNode(a) && jasmine.isDomNode(b)) { return a === b; } if (a instanceof Date && b instanceof Date) { return a.getTime() == b.getTime(); } if (a.jasmineMatches) { return a.jasmineMatches(b); } if (b.jasmineMatches) { return b.jasmineMatches(a); } if (a instanceof jasmine.Matchers.ObjectContaining) { return a.matches(b); } if (b instanceof jasmine.Matchers.ObjectContaining) { return b.matches(a); } if (jasmine.isString_(a) && jasmine.isString_(b)) { return (a == b); } if (jasmine.isNumber_(a) && jasmine.isNumber_(b)) { return (a == b); } if (a instanceof RegExp && b instanceof RegExp) { return this.compareRegExps_(a, b, mismatchKeys, mismatchValues); } if (typeof a === "object" && typeof b === "object") { return this.compareObjects_(a, b, mismatchKeys, mismatchValues); } //Straight check return (a === b); }; jasmine.Env.prototype.contains_ = function(haystack, needle) { if (jasmine.isArray_(haystack)) { for (var i = 0; i < haystack.length; i++) { if (this.equals_(haystack[i], needle)) return true; } return false; } return haystack.indexOf(needle) >= 0; }; jasmine.Env.prototype.addEqualityTester = function(equalityTester) { this.equalityTesters_.push(equalityTester); }; /** No-op base class for Jasmine reporters. * * @constructor */ jasmine.Reporter = function() { }; //noinspection JSUnusedLocalSymbols jasmine.Reporter.prototype.reportRunnerStarting = function(runner) { }; //noinspection JSUnusedLocalSymbols jasmine.Reporter.prototype.reportRunnerResults = function(runner) { }; //noinspection JSUnusedLocalSymbols jasmine.Reporter.prototype.reportSuiteResults = function(suite) { }; //noinspection JSUnusedLocalSymbols jasmine.Reporter.prototype.reportSpecStarting = function(spec) { }; //noinspection JSUnusedLocalSymbols jasmine.Reporter.prototype.reportSpecResults = function(spec) { }; //noinspection JSUnusedLocalSymbols jasmine.Reporter.prototype.log = function(str) { }; /** * Blocks are functions with executable code that make up a spec. * * @constructor * @param {jasmine.Env} env * @param {Function} func * @param {jasmine.Spec} spec */ jasmine.Block = function(env, func, spec) { this.env = env; this.func = func; this.spec = spec; }; jasmine.Block.prototype.execute = function(onComplete) { if (!jasmine.CATCH_EXCEPTIONS) { this.func.apply(this.spec); } else { try { this.func.apply(this.spec); } catch (e) { this.spec.fail(e); } } onComplete(); }; /** JavaScript API reporter. * * @constructor */ jasmine.JsApiReporter = function() { this.started = false; this.finished = false; this.suites_ = []; this.results_ = {}; }; jasmine.JsApiReporter.prototype.reportRunnerStarting = function(runner) { this.started = true; var suites = runner.topLevelSuites(); for (var i = 0; i < suites.length; i++) { var suite = suites[i]; this.suites_.push(this.summarize_(suite)); } }; jasmine.JsApiReporter.prototype.suites = function() { return this.suites_; }; jasmine.JsApiReporter.prototype.summarize_ = function(suiteOrSpec) { var isSuite = suiteOrSpec instanceof jasmine.Suite; var summary = { id: suiteOrSpec.id, name: suiteOrSpec.description, type: isSuite ? 'suite' : 'spec', children: [] }; if (isSuite) { var children = suiteOrSpec.children(); for (var i = 0; i < children.length; i++) { summary.children.push(this.summarize_(children[i])); } } return summary; }; jasmine.JsApiReporter.prototype.results = function() { return this.results_; }; jasmine.JsApiReporter.prototype.resultsForSpec = function(specId) { return this.results_[specId]; }; //noinspection JSUnusedLocalSymbols jasmine.JsApiReporter.prototype.reportRunnerResults = function(runner) { this.finished = true; }; //noinspection JSUnusedLocalSymbols jasmine.JsApiReporter.prototype.reportSuiteResults = function(suite) { }; //noinspection JSUnusedLocalSymbols jasmine.JsApiReporter.prototype.reportSpecResults = function(spec) { this.results_[spec.id] = { messages: spec.results().getItems(), result: spec.results().failedCount > 0 ? "failed" : "passed" }; }; //noinspection JSUnusedLocalSymbols jasmine.JsApiReporter.prototype.log = function(str) { }; jasmine.JsApiReporter.prototype.resultsForSpecs = function(specIds){ var results = {}; for (var i = 0; i < specIds.length; i++) { var specId = specIds[i]; results[specId] = this.summarizeResult_(this.results_[specId]); } return results; }; jasmine.JsApiReporter.prototype.summarizeResult_ = function(result){ var summaryMessages = []; var messagesLength = result.messages.length; for (var messageIndex = 0; messageIndex < messagesLength; messageIndex++) { var resultMessage = result.messages[messageIndex]; summaryMessages.push({ text: resultMessage.type == 'log' ? resultMessage.toString() : jasmine.undefined, passed: resultMessage.passed ? resultMessage.passed() : true, type: resultMessage.type, message: resultMessage.message, trace: { stack: resultMessage.passed && !resultMessage.passed() ? resultMessage.trace.stack : jasmine.undefined } }); } return { result : result.result, messages : summaryMessages }; }; /** * @constructor * @param {jasmine.Env} env * @param actual * @param {jasmine.Spec} spec */ jasmine.Matchers = function(env, actual, spec, opt_isNot) { this.env = env; this.actual = actual; this.spec = spec; this.isNot = opt_isNot || false; this.reportWasCalled_ = false; }; // todo: @deprecated as of Jasmine 0.11, remove soon [xw] jasmine.Matchers.pp = function(str) { throw new Error("jasmine.Matchers.pp() is no longer supported, please use jasmine.pp() instead!"); }; // todo: @deprecated Deprecated as of Jasmine 0.10. Rewrite your custom matchers to return true or false. [xw] jasmine.Matchers.prototype.report = function(result, failing_message, details) { throw new Error("As of jasmine 0.11, custom matchers must be implemented differently -- please see jasmine docs"); }; jasmine.Matchers.wrapInto_ = function(prototype, matchersClass) { for (var methodName in prototype) { if (methodName == 'report') continue; var orig = prototype[methodName]; matchersClass.prototype[methodName] = jasmine.Matchers.matcherFn_(methodName, orig); } }; jasmine.Matchers.matcherFn_ = function(matcherName, matcherFunction) { return function() { var matcherArgs = jasmine.util.argsToArray(arguments); var result = matcherFunction.apply(this, arguments); if (this.isNot) { result = !result; } if (this.reportWasCalled_) return result; var message; if (!result) { if (this.message) { message = this.message.apply(this, arguments); if (jasmine.isArray_(message)) { message = message[this.isNot ? 1 : 0]; } } else { var englishyPredicate = matcherName.replace(/[A-Z]/g, function(s) { return ' ' + s.toLowerCase(); }); message = "Expected " + jasmine.pp(this.actual) + (this.isNot ? " not " : " ") + englishyPredicate; if (matcherArgs.length > 0) { for (var i = 0; i < matcherArgs.length; i++) { if (i > 0) message += ","; message += " " + jasmine.pp(matcherArgs[i]); } } message += "."; } } var expectationResult = new jasmine.ExpectationResult({ matcherName: matcherName, passed: result, expected: matcherArgs.length > 1 ? matcherArgs : matcherArgs[0], actual: this.actual, message: message }); this.spec.addMatcherResult(expectationResult); return jasmine.undefined; }; }; /** * toBe: compares the actual to the expected using === * @param expected */ jasmine.Matchers.prototype.toBe = function(expected) { return this.actual === expected; }; /** * toNotBe: compares the actual to the expected using !== * @param expected * @deprecated as of 1.0. Use not.toBe() instead. */ jasmine.Matchers.prototype.toNotBe = function(expected) { return this.actual !== expected; }; /** * toEqual: compares the actual to the expected using common sense equality. Handles Objects, Arrays, etc. * * @param expected */ jasmine.Matchers.prototype.toEqual = function(expected) { return this.env.equals_(this.actual, expected); }; /** * toNotEqual: compares the actual to the expected using the ! of jasmine.Matchers.toEqual * @param expected * @deprecated as of 1.0. Use not.toEqual() instead. */ jasmine.Matchers.prototype.toNotEqual = function(expected) { return !this.env.equals_(this.actual, expected); }; /** * Matcher that compares the actual to the expected using a regular expression. Constructs a RegExp, so takes * a pattern or a String. * * @param expected */ jasmine.Matchers.prototype.toMatch = function(expected) { return new RegExp(expected).test(this.actual); }; /** * Matcher that compares the actual to the expected using the boolean inverse of jasmine.Matchers.toMatch * @param expected * @deprecated as of 1.0. Use not.toMatch() instead. */ jasmine.Matchers.prototype.toNotMatch = function(expected) { return !(new RegExp(expected).test(this.actual)); }; /** * Matcher that compares the actual to jasmine.undefined. */ jasmine.Matchers.prototype.toBeDefined = function() { return (this.actual !== jasmine.undefined); }; /** * Matcher that compares the actual to jasmine.undefined. */ jasmine.Matchers.prototype.toBeUndefined = function() { return (this.actual === jasmine.undefined); }; /** * Matcher that compares the actual to null. */ jasmine.Matchers.prototype.toBeNull = function() { return (this.actual === null); }; /** * Matcher that compares the actual to NaN. */ jasmine.Matchers.prototype.toBeNaN = function() { this.message = function() { return [ "Expected " + jasmine.pp(this.actual) + " to be NaN." ]; }; return (this.actual !== this.actual); }; /** * Matcher that boolean not-nots the actual. */ jasmine.Matchers.prototype.toBeTruthy = function() { return !!this.actual; }; /** * Matcher that boolean nots the actual. */ jasmine.Matchers.prototype.toBeFalsy = function() { return !this.actual; }; /** * Matcher that checks to see if the actual, a Jasmine spy, was called. */ jasmine.Matchers.prototype.toHaveBeenCalled = function() { if (arguments.length > 0) { throw new Error('toHaveBeenCalled does not take arguments, use toHaveBeenCalledWith'); } if (!jasmine.isSpy(this.actual)) { throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); } this.message = function() { return [ "Expected spy " + this.actual.identity + " to have been called.", "Expected spy " + this.actual.identity + " not to have been called." ]; }; return this.actual.wasCalled; }; /** @deprecated Use expect(xxx).toHaveBeenCalled() instead */ jasmine.Matchers.prototype.wasCalled = jasmine.Matchers.prototype.toHaveBeenCalled; /** * Matcher that checks to see if the actual, a Jasmine spy, was not called. * * @deprecated Use expect(xxx).not.toHaveBeenCalled() instead */ jasmine.Matchers.prototype.wasNotCalled = function() { if (arguments.length > 0) { throw new Error('wasNotCalled does not take arguments'); } if (!jasmine.isSpy(this.actual)) { throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); } this.message = function() { return [ "Expected spy " + this.actual.identity + " to not have been called.", "Expected spy " + this.actual.identity + " to have been called." ]; }; return !this.actual.wasCalled; }; /** * Matcher that checks to see if the actual, a Jasmine spy, was called with a set of parameters. * * @example * */ jasmine.Matchers.prototype.toHaveBeenCalledWith = function() { var expectedArgs = jasmine.util.argsToArray(arguments); if (!jasmine.isSpy(this.actual)) { throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); } this.message = function() { var invertedMessage = "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was."; var positiveMessage = ""; if (this.actual.callCount === 0) { positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called."; } else { positiveMessage = "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but actual calls were " + jasmine.pp(this.actual.argsForCall).replace(/^\[ | \]$/g, '') } return [positiveMessage, invertedMessage]; }; return this.env.contains_(this.actual.argsForCall, expectedArgs); }; /** @deprecated Use expect(xxx).toHaveBeenCalledWith() instead */ jasmine.Matchers.prototype.wasCalledWith = jasmine.Matchers.prototype.toHaveBeenCalledWith; /** @deprecated Use expect(xxx).not.toHaveBeenCalledWith() instead */ jasmine.Matchers.prototype.wasNotCalledWith = function() { var expectedArgs = jasmine.util.argsToArray(arguments); if (!jasmine.isSpy(this.actual)) { throw new Error('Expected a spy, but got ' + jasmine.pp(this.actual) + '.'); } this.message = function() { return [ "Expected spy not to have been called with " + jasmine.pp(expectedArgs) + " but it was", "Expected spy to have been called with " + jasmine.pp(expectedArgs) + " but it was" ]; }; return !this.env.contains_(this.actual.argsForCall, expectedArgs); }; /** * Matcher that checks that the expected item is an element in the actual Array. * * @param {Object} expected */ jasmine.Matchers.prototype.toContain = function(expected) { return this.env.contains_(this.actual, expected); }; /** * Matcher that checks that the expected item is NOT an element in the actual Array. * * @param {Object} expected * @deprecated as of 1.0. Use not.toContain() instead. */ jasmine.Matchers.prototype.toNotContain = function(expected) { return !this.env.contains_(this.actual, expected); }; jasmine.Matchers.prototype.toBeLessThan = function(expected) { return this.actual < expected; }; jasmine.Matchers.prototype.toBeGreaterThan = function(expected) { return this.actual > expected; }; /** * Matcher that checks that the expected item is equal to the actual item * up to a given level of decimal precision (default 2). * * @param {Number} expected * @param {Number} precision, as number of decimal places */ jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { if (!(precision === 0)) { precision = precision || 2; } return Math.abs(expected - this.actual) < (Math.pow(10, -precision) / 2); }; /** * Matcher that checks that the expected exception was thrown by the actual. * * @param {String} [expected] */ jasmine.Matchers.prototype.toThrow = function(expected) { var result = false; var exception; if (typeof this.actual != 'function') { throw new Error('Actual is not a function'); } try { this.actual(); } catch (e) { exception = e; } if (exception) { result = (expected === jasmine.undefined || this.env.equals_(exception.message || exception, expected.message || expected)); } var not = this.isNot ? "not " : ""; this.message = function() { if (exception && (expected === jasmine.undefined || !this.env.equals_(exception.message || exception, expected.message || expected))) { return ["Expected function " + not + "to throw", expected ? expected.message || expected : "an exception", ", but it threw", exception.message || exception].join(' '); } else { return "Expected function to throw an exception."; } }; return result; }; jasmine.Matchers.Any = function(expectedClass) { this.expectedClass = expectedClass; }; jasmine.Matchers.Any.prototype.jasmineMatches = function(other) { if (this.expectedClass == String) { return typeof other == 'string' || other instanceof String; } if (this.expectedClass == Number) { return typeof other == 'number' || other instanceof Number; } if (this.expectedClass == Function) { return typeof other == 'function' || other instanceof Function; } if (this.expectedClass == Object) { return typeof other == 'object'; } return other instanceof this.expectedClass; }; jasmine.Matchers.Any.prototype.jasmineToString = function() { return ''; }; jasmine.Matchers.ObjectContaining = function (sample) { this.sample = sample; }; jasmine.Matchers.ObjectContaining.prototype.jasmineMatches = function(other, mismatchKeys, mismatchValues) { mismatchKeys = mismatchKeys || []; mismatchValues = mismatchValues || []; var env = jasmine.getEnv(); var hasKey = function(obj, keyName) { return obj != null && obj[keyName] !== jasmine.undefined; }; for (var property in this.sample) { if (!hasKey(other, property) && hasKey(this.sample, property)) { mismatchKeys.push("expected has key '" + property + "', but missing from actual."); } else if (!env.equals_(this.sample[property], other[property], mismatchKeys, mismatchValues)) { mismatchValues.push("'" + property + "' was '" + (other[property] ? jasmine.util.htmlEscape(other[property].toString()) : other[property]) + "' in expected, but was '" + (this.sample[property] ? jasmine.util.htmlEscape(this.sample[property].toString()) : this.sample[property]) + "' in actual."); } } return (mismatchKeys.length === 0 && mismatchValues.length === 0); }; jasmine.Matchers.ObjectContaining.prototype.jasmineToString = function () { return ""; }; // Mock setTimeout, clearTimeout // Contributed by Pivotal Computer Systems, www.pivotalsf.com jasmine.FakeTimer = function() { this.reset(); var self = this; self.setTimeout = function(funcToCall, millis) { self.timeoutsMade++; self.scheduleFunction(self.timeoutsMade, funcToCall, millis, false); return self.timeoutsMade; }; self.setInterval = function(funcToCall, millis) { self.timeoutsMade++; self.scheduleFunction(self.timeoutsMade, funcToCall, millis, true); return self.timeoutsMade; }; self.clearTimeout = function(timeoutKey) { self.scheduledFunctions[timeoutKey] = jasmine.undefined; }; self.clearInterval = function(timeoutKey) { self.scheduledFunctions[timeoutKey] = jasmine.undefined; }; }; jasmine.FakeTimer.prototype.reset = function() { this.timeoutsMade = 0; this.scheduledFunctions = {}; this.nowMillis = 0; }; jasmine.FakeTimer.prototype.tick = function(millis) { var oldMillis = this.nowMillis; var newMillis = oldMillis + millis; this.runFunctionsWithinRange(oldMillis, newMillis); this.nowMillis = newMillis; }; jasmine.FakeTimer.prototype.runFunctionsWithinRange = function(oldMillis, nowMillis) { var scheduledFunc; var funcsToRun = []; for (var timeoutKey in this.scheduledFunctions) { scheduledFunc = this.scheduledFunctions[timeoutKey]; if (scheduledFunc != jasmine.undefined && scheduledFunc.runAtMillis >= oldMillis && scheduledFunc.runAtMillis <= nowMillis) { funcsToRun.push(scheduledFunc); this.scheduledFunctions[timeoutKey] = jasmine.undefined; } } if (funcsToRun.length > 0) { funcsToRun.sort(function(a, b) { return a.runAtMillis - b.runAtMillis; }); for (var i = 0; i < funcsToRun.length; ++i) { try { var funcToRun = funcsToRun[i]; this.nowMillis = funcToRun.runAtMillis; funcToRun.funcToCall(); if (funcToRun.recurring) { this.scheduleFunction(funcToRun.timeoutKey, funcToRun.funcToCall, funcToRun.millis, true); } } catch(e) { } } this.runFunctionsWithinRange(oldMillis, nowMillis); } }; jasmine.FakeTimer.prototype.scheduleFunction = function(timeoutKey, funcToCall, millis, recurring) { this.scheduledFunctions[timeoutKey] = { runAtMillis: this.nowMillis + millis, funcToCall: funcToCall, recurring: recurring, timeoutKey: timeoutKey, millis: millis }; }; /** * @namespace */ jasmine.Clock = { defaultFakeTimer: new jasmine.FakeTimer(), reset: function() { jasmine.Clock.assertInstalled(); jasmine.Clock.defaultFakeTimer.reset(); }, tick: function(millis) { jasmine.Clock.assertInstalled(); jasmine.Clock.defaultFakeTimer.tick(millis); }, runFunctionsWithinRange: function(oldMillis, nowMillis) { jasmine.Clock.defaultFakeTimer.runFunctionsWithinRange(oldMillis, nowMillis); }, scheduleFunction: function(timeoutKey, funcToCall, millis, recurring) { jasmine.Clock.defaultFakeTimer.scheduleFunction(timeoutKey, funcToCall, millis, recurring); }, useMock: function() { if (!jasmine.Clock.isInstalled()) { var spec = jasmine.getEnv().currentSpec; spec.after(jasmine.Clock.uninstallMock); jasmine.Clock.installMock(); } }, installMock: function() { jasmine.Clock.installed = jasmine.Clock.defaultFakeTimer; }, uninstallMock: function() { jasmine.Clock.assertInstalled(); jasmine.Clock.installed = jasmine.Clock.real; }, real: { setTimeout: jasmine.getGlobal().setTimeout, clearTimeout: jasmine.getGlobal().clearTimeout, setInterval: jasmine.getGlobal().setInterval, clearInterval: jasmine.getGlobal().clearInterval }, assertInstalled: function() { if (!jasmine.Clock.isInstalled()) { throw new Error("Mock clock is not installed, use jasmine.Clock.useMock()"); } }, isInstalled: function() { return jasmine.Clock.installed == jasmine.Clock.defaultFakeTimer; }, installed: null }; jasmine.Clock.installed = jasmine.Clock.real; //else for IE support jasmine.getGlobal().setTimeout = function(funcToCall, millis) { if (jasmine.Clock.installed.setTimeout.apply) { return jasmine.Clock.installed.setTimeout.apply(this, arguments); } else { return jasmine.Clock.installed.setTimeout(funcToCall, millis); } }; jasmine.getGlobal().setInterval = function(funcToCall, millis) { if (jasmine.Clock.installed.setInterval.apply) { return jasmine.Clock.installed.setInterval.apply(this, arguments); } else { return jasmine.Clock.installed.setInterval(funcToCall, millis); } }; jasmine.getGlobal().clearTimeout = function(timeoutKey) { if (jasmine.Clock.installed.clearTimeout.apply) { return jasmine.Clock.installed.clearTimeout.apply(this, arguments); } else { return jasmine.Clock.installed.clearTimeout(timeoutKey); } }; jasmine.getGlobal().clearInterval = function(timeoutKey) { if (jasmine.Clock.installed.clearTimeout.apply) { return jasmine.Clock.installed.clearInterval.apply(this, arguments); } else { return jasmine.Clock.installed.clearInterval(timeoutKey); } }; /** * @constructor */ jasmine.MultiReporter = function() { this.subReporters_ = []; }; jasmine.util.inherit(jasmine.MultiReporter, jasmine.Reporter); jasmine.MultiReporter.prototype.addReporter = function(reporter) { this.subReporters_.push(reporter); }; (function() { var functionNames = [ "reportRunnerStarting", "reportRunnerResults", "reportSuiteResults", "reportSpecStarting", "reportSpecResults", "log" ]; for (var i = 0; i < functionNames.length; i++) { var functionName = functionNames[i]; jasmine.MultiReporter.prototype[functionName] = (function(functionName) { return function() { for (var j = 0; j < this.subReporters_.length; j++) { var subReporter = this.subReporters_[j]; if (subReporter[functionName]) { subReporter[functionName].apply(subReporter, arguments); } } }; })(functionName); } })(); /** * Holds results for a set of Jasmine spec. Allows for the results array to hold another jasmine.NestedResults * * @constructor */ jasmine.NestedResults = function() { /** * The total count of results */ this.totalCount = 0; /** * Number of passed results */ this.passedCount = 0; /** * Number of failed results */ this.failedCount = 0; /** * Was this suite/spec skipped? */ this.skipped = false; /** * @ignore */ this.items_ = []; }; /** * Roll up the result counts. * * @param result */ jasmine.NestedResults.prototype.rollupCounts = function(result) { this.totalCount += result.totalCount; this.passedCount += result.passedCount; this.failedCount += result.failedCount; }; /** * Adds a log message. * @param values Array of message parts which will be concatenated later. */ jasmine.NestedResults.prototype.log = function(values) { this.items_.push(new jasmine.MessageResult(values)); }; /** * Getter for the results: message & results. */ jasmine.NestedResults.prototype.getItems = function() { return this.items_; }; /** * Adds a result, tracking counts (total, passed, & failed) * @param {jasmine.ExpectationResult|jasmine.NestedResults} result */ jasmine.NestedResults.prototype.addResult = function(result) { if (result.type != 'log') { if (result.items_) { this.rollupCounts(result); } else { this.totalCount++; if (result.passed()) { this.passedCount++; } else { this.failedCount++; } } } this.items_.push(result); }; /** * @returns {Boolean} True if everything below passed */ jasmine.NestedResults.prototype.passed = function() { return this.passedCount === this.totalCount; }; /** * Base class for pretty printing for expectation results. */ jasmine.PrettyPrinter = function() { this.ppNestLevel_ = 0; }; /** * Formats a value in a nice, human-readable string. * * @param value */ jasmine.PrettyPrinter.prototype.format = function(value) { this.ppNestLevel_++; try { if (value === jasmine.undefined) { this.emitScalar('undefined'); } else if (value === null) { this.emitScalar('null'); } else if (value === jasmine.getGlobal()) { this.emitScalar(''); } else if (value.jasmineToString) { this.emitScalar(value.jasmineToString()); } else if (typeof value === 'string') { this.emitString(value); } else if (jasmine.isSpy(value)) { this.emitScalar("spy on " + value.identity); } else if (value instanceof RegExp) { this.emitScalar(value.toString()); } else if (typeof value === 'function') { this.emitScalar('Function'); } else if (typeof value.nodeType === 'number') { this.emitScalar('HTMLNode'); } else if (value instanceof Date) { this.emitScalar('Date(' + value + ')'); } else if (value.__Jasmine_been_here_before__) { this.emitScalar(''); } else if (jasmine.isArray_(value) || typeof value == 'object') { value.__Jasmine_been_here_before__ = true; if (jasmine.isArray_(value)) { this.emitArray(value); } else { this.emitObject(value); } delete value.__Jasmine_been_here_before__; } else { this.emitScalar(value.toString()); } } finally { this.ppNestLevel_--; } }; jasmine.PrettyPrinter.prototype.iterateObject = function(obj, fn) { for (var property in obj) { if (!obj.hasOwnProperty(property)) continue; if (property == '__Jasmine_been_here_before__') continue; fn(property, obj.__lookupGetter__ ? (obj.__lookupGetter__(property) !== jasmine.undefined && obj.__lookupGetter__(property) !== null) : false); } }; jasmine.PrettyPrinter.prototype.emitArray = jasmine.unimplementedMethod_; jasmine.PrettyPrinter.prototype.emitObject = jasmine.unimplementedMethod_; jasmine.PrettyPrinter.prototype.emitScalar = jasmine.unimplementedMethod_; jasmine.PrettyPrinter.prototype.emitString = jasmine.unimplementedMethod_; jasmine.StringPrettyPrinter = function() { jasmine.PrettyPrinter.call(this); this.string = ''; }; jasmine.util.inherit(jasmine.StringPrettyPrinter, jasmine.PrettyPrinter); jasmine.StringPrettyPrinter.prototype.emitScalar = function(value) { this.append(value); }; jasmine.StringPrettyPrinter.prototype.emitString = function(value) { this.append("'" + value + "'"); }; jasmine.StringPrettyPrinter.prototype.emitArray = function(array) { if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) { this.append("Array"); return; } this.append('[ '); for (var i = 0; i < array.length; i++) { if (i > 0) { this.append(', '); } this.format(array[i]); } this.append(' ]'); }; jasmine.StringPrettyPrinter.prototype.emitObject = function(obj) { if (this.ppNestLevel_ > jasmine.MAX_PRETTY_PRINT_DEPTH) { this.append("Object"); return; } var self = this; this.append('{ '); var first = true; this.iterateObject(obj, function(property, isGetter) { if (first) { first = false; } else { self.append(', '); } self.append(property); self.append(' : '); if (isGetter) { self.append(''); } else { self.format(obj[property]); } }); this.append(' }'); }; jasmine.StringPrettyPrinter.prototype.append = function(value) { this.string += value; }; jasmine.Queue = function(env) { this.env = env; // parallel to blocks. each true value in this array means the block will // get executed even if we abort this.ensured = []; this.blocks = []; this.running = false; this.index = 0; this.offset = 0; this.abort = false; }; jasmine.Queue.prototype.addBefore = function(block, ensure) { if (ensure === jasmine.undefined) { ensure = false; } this.blocks.unshift(block); this.ensured.unshift(ensure); }; jasmine.Queue.prototype.add = function(block, ensure) { if (ensure === jasmine.undefined) { ensure = false; } this.blocks.push(block); this.ensured.push(ensure); }; jasmine.Queue.prototype.insertNext = function(block, ensure) { if (ensure === jasmine.undefined) { ensure = false; } this.ensured.splice((this.index + this.offset + 1), 0, ensure); this.blocks.splice((this.index + this.offset + 1), 0, block); this.offset++; }; jasmine.Queue.prototype.start = function(onComplete) { this.running = true; this.onComplete = onComplete; this.next_(); }; jasmine.Queue.prototype.isRunning = function() { return this.running; }; jasmine.Queue.LOOP_DONT_RECURSE = true; jasmine.Queue.prototype.next_ = function() { var self = this; var goAgain = true; while (goAgain) { goAgain = false; if (self.index < self.blocks.length && !(this.abort && !this.ensured[self.index])) { var calledSynchronously = true; var completedSynchronously = false; var onComplete = function () { if (jasmine.Queue.LOOP_DONT_RECURSE && calledSynchronously) { completedSynchronously = true; return; } if (self.blocks[self.index].abort) { self.abort = true; } self.offset = 0; self.index++; var now = new Date().getTime(); if (self.env.updateInterval && now - self.env.lastUpdate > self.env.updateInterval) { self.env.lastUpdate = now; self.env.setTimeout(function() { self.next_(); }, 0); } else { if (jasmine.Queue.LOOP_DONT_RECURSE && completedSynchronously) { goAgain = true; } else { self.next_(); } } }; self.blocks[self.index].execute(onComplete); calledSynchronously = false; if (completedSynchronously) { onComplete(); } } else { self.running = false; if (self.onComplete) { self.onComplete(); } } } }; jasmine.Queue.prototype.results = function() { var results = new jasmine.NestedResults(); for (var i = 0; i < this.blocks.length; i++) { if (this.blocks[i].results) { results.addResult(this.blocks[i].results()); } } return results; }; /** * Runner * * @constructor * @param {jasmine.Env} env */ jasmine.Runner = function(env) { var self = this; self.env = env; self.queue = new jasmine.Queue(env); self.before_ = []; self.after_ = []; self.suites_ = []; }; jasmine.Runner.prototype.execute = function() { var self = this; if (self.env.reporter.reportRunnerStarting) { self.env.reporter.reportRunnerStarting(this); } self.queue.start(function () { self.finishCallback(); }); }; jasmine.Runner.prototype.beforeEach = function(beforeEachFunction) { beforeEachFunction.typeName = 'beforeEach'; this.before_.splice(0,0,beforeEachFunction); }; jasmine.Runner.prototype.afterEach = function(afterEachFunction) { afterEachFunction.typeName = 'afterEach'; this.after_.splice(0,0,afterEachFunction); }; jasmine.Runner.prototype.finishCallback = function() { this.env.reporter.reportRunnerResults(this); }; jasmine.Runner.prototype.addSuite = function(suite) { this.suites_.push(suite); }; jasmine.Runner.prototype.add = function(block) { if (block instanceof jasmine.Suite) { this.addSuite(block); } this.queue.add(block); }; jasmine.Runner.prototype.specs = function () { var suites = this.suites(); var specs = []; for (var i = 0; i < suites.length; i++) { specs = specs.concat(suites[i].specs()); } return specs; }; jasmine.Runner.prototype.suites = function() { return this.suites_; }; jasmine.Runner.prototype.topLevelSuites = function() { var topLevelSuites = []; for (var i = 0; i < this.suites_.length; i++) { if (!this.suites_[i].parentSuite) { topLevelSuites.push(this.suites_[i]); } } return topLevelSuites; }; jasmine.Runner.prototype.results = function() { return this.queue.results(); }; /** * Internal representation of a Jasmine specification, or test. * * @constructor * @param {jasmine.Env} env * @param {jasmine.Suite} suite * @param {String} description */ jasmine.Spec = function(env, suite, description) { if (!env) { throw new Error('jasmine.Env() required'); } if (!suite) { throw new Error('jasmine.Suite() required'); } var spec = this; spec.id = env.nextSpecId ? env.nextSpecId() : null; spec.env = env; spec.suite = suite; spec.description = description; spec.queue = new jasmine.Queue(env); spec.afterCallbacks = []; spec.spies_ = []; spec.results_ = new jasmine.NestedResults(); spec.results_.description = description; spec.matchersClass = null; }; jasmine.Spec.prototype.getFullName = function() { return this.suite.getFullName() + ' ' + this.description + '.'; }; jasmine.Spec.prototype.results = function() { return this.results_; }; /** * All parameters are pretty-printed and concatenated together, then written to the spec's output. * * Be careful not to leave calls to jasmine.log in production code. */ jasmine.Spec.prototype.log = function() { return this.results_.log(arguments); }; jasmine.Spec.prototype.runs = function (func) { var block = new jasmine.Block(this.env, func, this); this.addToQueue(block); return this; }; jasmine.Spec.prototype.addToQueue = function (block) { if (this.queue.isRunning()) { this.queue.insertNext(block); } else { this.queue.add(block); } }; /** * @param {jasmine.ExpectationResult} result */ jasmine.Spec.prototype.addMatcherResult = function(result) { this.results_.addResult(result); }; jasmine.Spec.prototype.expect = function(actual) { var positive = new (this.getMatchersClass_())(this.env, actual, this); positive.not = new (this.getMatchersClass_())(this.env, actual, this, true); return positive; }; /** * Waits a fixed time period before moving to the next block. * * @deprecated Use waitsFor() instead * @param {Number} timeout milliseconds to wait */ jasmine.Spec.prototype.waits = function(timeout) { var waitsFunc = new jasmine.WaitsBlock(this.env, timeout, this); this.addToQueue(waitsFunc); return this; }; /** * Waits for the latchFunction to return true before proceeding to the next block. * * @param {Function} latchFunction * @param {String} optional_timeoutMessage * @param {Number} optional_timeout */ jasmine.Spec.prototype.waitsFor = function(latchFunction, optional_timeoutMessage, optional_timeout) { var latchFunction_ = null; var optional_timeoutMessage_ = null; var optional_timeout_ = null; for (var i = 0; i < arguments.length; i++) { var arg = arguments[i]; switch (typeof arg) { case 'function': latchFunction_ = arg; break; case 'string': optional_timeoutMessage_ = arg; break; case 'number': optional_timeout_ = arg; break; } } var waitsForFunc = new jasmine.WaitsForBlock(this.env, optional_timeout_, latchFunction_, optional_timeoutMessage_, this); this.addToQueue(waitsForFunc); return this; }; jasmine.Spec.prototype.fail = function (e) { var expectationResult = new jasmine.ExpectationResult({ passed: false, message: e ? jasmine.util.formatException(e) : 'Exception', trace: { stack: e.stack } }); this.results_.addResult(expectationResult); }; jasmine.Spec.prototype.getMatchersClass_ = function() { return this.matchersClass || this.env.matchersClass; }; jasmine.Spec.prototype.addMatchers = function(matchersPrototype) { var parent = this.getMatchersClass_(); var newMatchersClass = function() { parent.apply(this, arguments); }; jasmine.util.inherit(newMatchersClass, parent); jasmine.Matchers.wrapInto_(matchersPrototype, newMatchersClass); this.matchersClass = newMatchersClass; }; jasmine.Spec.prototype.finishCallback = function() { this.env.reporter.reportSpecResults(this); }; jasmine.Spec.prototype.finish = function(onComplete) { this.removeAllSpies(); this.finishCallback(); if (onComplete) { onComplete(); } }; jasmine.Spec.prototype.after = function(doAfter) { if (this.queue.isRunning()) { this.queue.add(new jasmine.Block(this.env, doAfter, this), true); } else { this.afterCallbacks.unshift(doAfter); } }; jasmine.Spec.prototype.execute = function(onComplete) { var spec = this; if (!spec.env.specFilter(spec)) { spec.results_.skipped = true; spec.finish(onComplete); return; } this.env.reporter.reportSpecStarting(this); spec.env.currentSpec = spec; spec.addBeforesAndAftersToQueue(); spec.queue.start(function () { spec.finish(onComplete); }); }; jasmine.Spec.prototype.addBeforesAndAftersToQueue = function() { var runner = this.env.currentRunner(); var i; for (var suite = this.suite; suite; suite = suite.parentSuite) { for (i = 0; i < suite.before_.length; i++) { this.queue.addBefore(new jasmine.Block(this.env, suite.before_[i], this)); } } for (i = 0; i < runner.before_.length; i++) { this.queue.addBefore(new jasmine.Block(this.env, runner.before_[i], this)); } for (i = 0; i < this.afterCallbacks.length; i++) { this.queue.add(new jasmine.Block(this.env, this.afterCallbacks[i], this), true); } for (suite = this.suite; suite; suite = suite.parentSuite) { for (i = 0; i < suite.after_.length; i++) { this.queue.add(new jasmine.Block(this.env, suite.after_[i], this), true); } } for (i = 0; i < runner.after_.length; i++) { this.queue.add(new jasmine.Block(this.env, runner.after_[i], this), true); } }; jasmine.Spec.prototype.explodes = function() { throw 'explodes function should not have been called'; }; jasmine.Spec.prototype.spyOn = function(obj, methodName, ignoreMethodDoesntExist) { if (obj == jasmine.undefined) { throw "spyOn could not find an object to spy upon for " + methodName + "()"; } if (!ignoreMethodDoesntExist && obj[methodName] === jasmine.undefined) { throw methodName + '() method does not exist'; } if (!ignoreMethodDoesntExist && obj[methodName] && obj[methodName].isSpy) { throw new Error(methodName + ' has already been spied upon'); } var spyObj = jasmine.createSpy(methodName); this.spies_.push(spyObj); spyObj.baseObj = obj; spyObj.methodName = methodName; spyObj.originalValue = obj[methodName]; obj[methodName] = spyObj; return spyObj; }; jasmine.Spec.prototype.removeAllSpies = function() { for (var i = 0; i < this.spies_.length; i++) { var spy = this.spies_[i]; spy.baseObj[spy.methodName] = spy.originalValue; } this.spies_ = []; }; /** * Internal representation of a Jasmine suite. * * @constructor * @param {jasmine.Env} env * @param {String} description * @param {Function} specDefinitions * @param {jasmine.Suite} parentSuite */ jasmine.Suite = function(env, description, specDefinitions, parentSuite) { var self = this; self.id = env.nextSuiteId ? env.nextSuiteId() : null; self.description = description; self.queue = new jasmine.Queue(env); self.parentSuite = parentSuite; self.env = env; self.before_ = []; self.after_ = []; self.children_ = []; self.suites_ = []; self.specs_ = []; }; jasmine.Suite.prototype.getFullName = function() { var fullName = this.description; for (var parentSuite = this.parentSuite; parentSuite; parentSuite = parentSuite.parentSuite) { fullName = parentSuite.description + ' ' + fullName; } return fullName; }; jasmine.Suite.prototype.finish = function(onComplete) { this.env.reporter.reportSuiteResults(this); this.finished = true; if (typeof(onComplete) == 'function') { onComplete(); } }; jasmine.Suite.prototype.beforeEach = function(beforeEachFunction) { beforeEachFunction.typeName = 'beforeEach'; this.before_.unshift(beforeEachFunction); }; jasmine.Suite.prototype.afterEach = function(afterEachFunction) { afterEachFunction.typeName = 'afterEach'; this.after_.unshift(afterEachFunction); }; jasmine.Suite.prototype.results = function() { return this.queue.results(); }; jasmine.Suite.prototype.add = function(suiteOrSpec) { this.children_.push(suiteOrSpec); if (suiteOrSpec instanceof jasmine.Suite) { this.suites_.push(suiteOrSpec); this.env.currentRunner().addSuite(suiteOrSpec); } else { this.specs_.push(suiteOrSpec); } this.queue.add(suiteOrSpec); }; jasmine.Suite.prototype.specs = function() { return this.specs_; }; jasmine.Suite.prototype.suites = function() { return this.suites_; }; jasmine.Suite.prototype.children = function() { return this.children_; }; jasmine.Suite.prototype.execute = function(onComplete) { var self = this; this.queue.start(function () { self.finish(onComplete); }); }; jasmine.WaitsBlock = function(env, timeout, spec) { this.timeout = timeout; jasmine.Block.call(this, env, null, spec); }; jasmine.util.inherit(jasmine.WaitsBlock, jasmine.Block); jasmine.WaitsBlock.prototype.execute = function (onComplete) { if (jasmine.VERBOSE) { this.env.reporter.log('>> Jasmine waiting for ' + this.timeout + ' ms...'); } this.env.setTimeout(function () { onComplete(); }, this.timeout); }; /** * A block which waits for some condition to become true, with timeout. * * @constructor * @extends jasmine.Block * @param {jasmine.Env} env The Jasmine environment. * @param {Number} timeout The maximum time in milliseconds to wait for the condition to become true. * @param {Function} latchFunction A function which returns true when the desired condition has been met. * @param {String} message The message to display if the desired condition hasn't been met within the given time period. * @param {jasmine.Spec} spec The Jasmine spec. */ jasmine.WaitsForBlock = function(env, timeout, latchFunction, message, spec) { this.timeout = timeout || env.defaultTimeoutInterval; this.latchFunction = latchFunction; this.message = message; this.totalTimeSpentWaitingForLatch = 0; jasmine.Block.call(this, env, null, spec); }; jasmine.util.inherit(jasmine.WaitsForBlock, jasmine.Block); jasmine.WaitsForBlock.TIMEOUT_INCREMENT = 10; jasmine.WaitsForBlock.prototype.execute = function(onComplete) { if (jasmine.VERBOSE) { this.env.reporter.log('>> Jasmine waiting for ' + (this.message || 'something to happen')); } var latchFunctionResult; try { latchFunctionResult = this.latchFunction.apply(this.spec); } catch (e) { this.spec.fail(e); onComplete(); return; } if (latchFunctionResult) { onComplete(); } else if (this.totalTimeSpentWaitingForLatch >= this.timeout) { var message = 'timed out after ' + this.timeout + ' msec waiting for ' + (this.message || 'something to happen'); this.spec.fail({ name: 'timeout', message: message }); this.abort = true; onComplete(); } else { this.totalTimeSpentWaitingForLatch += jasmine.WaitsForBlock.TIMEOUT_INCREMENT; var self = this; this.env.setTimeout(function() { self.execute(onComplete); }, jasmine.WaitsForBlock.TIMEOUT_INCREMENT); } }; jasmine.version_= { "major": 1, "minor": 3, "build": 1, "revision": 1354556913 }; es5-shim-4.4.1/tests/lib/jasmine_favicon.png000066400000000000000000000016111263422513500207250ustar00rootroot00000000000000PNG  IHDRagAMA asRGB cHRMz&u0`:pQ<bKGD pHYs  IDAT8˥KHTaOs8KT񒗌2"ZA-EЦMѦ-" EQ= -2Gr2oQR|7_LNO_fw{[Zld 2lŴ뉱+OjƓέ|k>;Fnδ"mz?4E]`_sk:ҜN#$a͆u+ggeߺz;]fDQjG58c(Θ6[,P4ɳ:d޹_/B@1347x?HT0'mEv"@)5ZM`?<~8ԊˋJɒdaTG$ыCXd :ܼYK.ir #j2)jU⚵n),+7Sc $9=bs z"`ĒU^:*)+XkϮs˳H  :]B2S5eL(eb65}}o<]r1ElɐR`gg#74xߵx[m$4s,Wc]0c$AVU%쫯oM4# `ρR1}p/3Nd-wGcJKWW/Hĝ7?g)&6<IENDB`es5-shim-4.4.1/tests/lib/json2.js000066400000000000000000000417001263422513500164600ustar00rootroot00000000000000/* http://www.JSON.org/json2.js 2009-08-17 Public Domain. NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK. See http://www.JSON.org/js.html This file creates a global JSON object containing two methods: stringify and parse. JSON.stringify(value, replacer, space) value any JavaScript value, usually an object or array. replacer an optional parameter that determines how object values are stringified for objects. It can be a function or an array of strings. space an optional parameter that specifies the indentation of nested structures. If it is omitted, the text will be packed without extra whitespace. If it is a number, it will specify the number of spaces to indent at each level. If it is a string (such as '\t' or ' '), it contains the characters used to indent at each level. This method produces a JSON text from a JavaScript value. When an object value is found, if the object contains a toJSON method, its toJSON method will be called and the result will be stringified. A toJSON method does not serialize: it returns the value represented by the name/value pair that should be serialized, or undefined if nothing should be serialized. The toJSON method will be passed the key associated with the value, and this will be bound to the value For example, this would serialize Dates as ISO strings. Date.prototype.toJSON = function (key) { function f(n) { // Format integers to have at least two digits. return n < 10 ? '0' + n : n; } return this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z'; }; You can provide an optional replacer method. It will be passed the key and value of each member, with this bound to the containing object. The value that is returned from your method will be serialized. If your method returns undefined, then the member will be excluded from the serialization. If the replacer parameter is an array of strings, then it will be used to select the members to be serialized. It filters the results such that only members with keys listed in the replacer array are stringified. Values that do not have JSON representations, such as undefined or functions, will not be serialized. Such values in objects will be dropped; in arrays they will be replaced with null. You can use a replacer function to replace those with JSON values. JSON.stringify(undefined) returns undefined. The optional space parameter produces a stringification of the value that is filled with line breaks and indentation to make it easier to read. If the space parameter is a non-empty string, then that string will be used for indentation. If the space parameter is a number, then the indentation will be that many spaces. Example: text = JSON.stringify(['e', {pluribus: 'unum'}]); // text is '["e",{"pluribus":"unum"}]' text = JSON.stringify(['e', {pluribus: 'unum'}], null, '\t'); // text is '[\n\t"e",\n\t{\n\t\t"pluribus": "unum"\n\t}\n]' text = JSON.stringify([new Date()], function (key, value) { return this[key] instanceof Date ? 'Date(' + this[key] + ')' : value; }); // text is '["Date(---current time---)"]' JSON.parse(text, reviver) This method parses a JSON text to produce an object or array. It can throw a SyntaxError exception. The optional reviver parameter is a function that can filter and transform the results. It receives each of the keys and values, and its return value is used instead of the original value. If it returns what it received, then the structure is not modified. If it returns undefined then the member is deleted. Example: // Parse the text. Values that look like ISO date strings will // be converted to Date objects. myData = JSON.parse(text, function (key, value) { var a; if (typeof value === 'string') { a = /^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}(?:\.\d*)?)Z$/.exec(value); if (a) { return new Date(Date.UTC(+a[1], +a[2] - 1, +a[3], +a[4], +a[5], +a[6])); } } return value; }); myData = JSON.parse('["Date(09/09/2001)"]', function (key, value) { var d; if (typeof value === 'string' && value.slice(0, 5) === 'Date(' && value.slice(-1) === ')') { d = new Date(value.slice(5, -1)); if (d) { return d; } } return value; }); This is a reference implementation. You are free to copy, modify, or redistribute. This code should be minified before deployment. See http://javascript.crockford.com/jsmin.html USE YOUR OWN COPY. IT IS EXTREMELY UNWISE TO LOAD CODE FROM SERVERS YOU DO NOT CONTROL. */ /*jslint evil: true */ /*members "", "\b", "\t", "\n", "\f", "\r", "\"", JSON, "\\", apply, call, charCodeAt, getUTCDate, getUTCFullYear, getUTCHours, getUTCMinutes, getUTCMonth, getUTCSeconds, hasOwnProperty, join, lastIndex, length, parse, prototype, push, replace, slice, stringify, test, toJSON, toString, valueOf */ "use strict"; // Create a JSON object only if one does not already exist. We create the // methods in a closure to avoid creating global variables. if (!this.JSON) { this.JSON = {}; } (function () { function f(n) { // Format integers to have at least two digits. return n < 10 ? '0' + n : n; } if (typeof Date.prototype.toJSON !== 'function') { Date.prototype.toJSON = function (key) { return isFinite(this.valueOf()) ? this.getUTCFullYear() + '-' + f(this.getUTCMonth() + 1) + '-' + f(this.getUTCDate()) + 'T' + f(this.getUTCHours()) + ':' + f(this.getUTCMinutes()) + ':' + f(this.getUTCSeconds()) + 'Z' : null; }; String.prototype.toJSON = Number.prototype.toJSON = Boolean.prototype.toJSON = function (key) { return this.valueOf(); }; } var cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, escapable = /[\\\"\x00-\x1f\x7f-\x9f\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g, gap, indent, meta = { // table of character substitutions '\b': '\\b', '\t': '\\t', '\n': '\\n', '\f': '\\f', '\r': '\\r', '"' : '\\"', '\\': '\\\\' }, rep; function quote(string) { // If the string contains no control characters, no quote characters, and no // backslash characters, then we can safely slap some quotes around it. // Otherwise we must also replace the offending characters with safe escape // sequences. escapable.lastIndex = 0; return escapable.test(string) ? '"' + string.replace(escapable, function (a) { var c = meta[a]; return typeof c === 'string' ? c : '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }) + '"' : '"' + string + '"'; } function str(key, holder) { // Produce a string from holder[key]. var i, // The loop counter. k, // The member key. v, // The member value. length, mind = gap, partial, value = holder[key]; // If the value has a toJSON method, call it to obtain a replacement value. if (value && typeof value === 'object' && typeof value.toJSON === 'function') { value = value.toJSON(key); } // If we were called with a replacer function, then call the replacer to // obtain a replacement value. if (typeof rep === 'function') { value = rep.call(holder, key, value); } // What happens next depends on the value's type. switch (typeof value) { case 'string': return quote(value); case 'number': // JSON numbers must be finite. Encode non-finite numbers as null. return isFinite(value) ? String(value) : 'null'; case 'boolean': case 'null': // If the value is a boolean or null, convert it to a string. Note: // typeof null does not produce 'null'. The case is included here in // the remote chance that this gets fixed someday. return String(value); // If the type is 'object', we might be dealing with an object or an array or // null. case 'object': // Due to a specification blunder in ECMAScript, typeof null is 'object', // so watch out for that case. if (!value) { return 'null'; } // Make an array to hold the partial results of stringifying this object value. gap += indent; partial = []; // Is the value an array? if (Object.prototype.toString.apply(value) === '[object Array]') { // The value is an array. Stringify every element. Use null as a placeholder // for non-JSON values. length = value.length; for (i = 0; i < length; i += 1) { partial[i] = str(i, value) || 'null'; } // Join all of the elements together, separated with commas, and wrap them in // brackets. v = partial.length === 0 ? '[]' : gap ? '[\n' + gap + partial.join(',\n' + gap) + '\n' + mind + ']' : '[' + partial.join(',') + ']'; gap = mind; return v; } // If the replacer is an array, use it to select the members to be stringified. if (rep && typeof rep === 'object') { length = rep.length; for (i = 0; i < length; i += 1) { k = rep[i]; if (typeof k === 'string') { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } else { // Otherwise, iterate through all of the keys in the object. for (k in value) { if (Object.hasOwnProperty.call(value, k)) { v = str(k, value); if (v) { partial.push(quote(k) + (gap ? ': ' : ':') + v); } } } } // Join all of the member texts together, separated with commas, // and wrap them in braces. v = partial.length === 0 ? '{}' : gap ? '{\n' + gap + partial.join(',\n' + gap) + '\n' + mind + '}' : '{' + partial.join(',') + '}'; gap = mind; return v; } } // If the JSON object does not yet have a stringify method, give it one. if (typeof JSON.stringify !== 'function') { JSON.stringify = function (value, replacer, space) { // The stringify method takes a value and an optional replacer, and an optional // space parameter, and returns a JSON text. The replacer can be a function // that can replace values, or an array of strings that will select the keys. // A default replacer method can be provided. Use of the space parameter can // produce text that is more easily readable. var i; gap = ''; indent = ''; // If the space parameter is a number, make an indent string containing that // many spaces. if (typeof space === 'number') { for (i = 0; i < space; i += 1) { indent += ' '; } // If the space parameter is a string, it will be used as the indent string. } else if (typeof space === 'string') { indent = space; } // If there is a replacer, it must be a function or an array. // Otherwise, throw an error. rep = replacer; if (replacer && typeof replacer !== 'function' && (typeof replacer !== 'object' || typeof replacer.length !== 'number')) { throw new Error('JSON.stringify'); } // Make a fake root object containing our value under the key of ''. // Return the result of stringifying the value. return str('', {'': value}); }; } // If the JSON object does not yet have a parse method, give it one. if (typeof JSON.parse !== 'function') { JSON.parse = function (text, reviver) { // The parse method takes a text and an optional reviver function, and returns // a JavaScript value if the text is a valid JSON text. var j; function walk(holder, key) { // The walk method is used to recursively walk the resulting structure so // that modifications can be made. var k, v, value = holder[key]; if (value && typeof value === 'object') { for (k in value) { if (Object.hasOwnProperty.call(value, k)) { v = walk(value, k); if (v !== undefined) { value[k] = v; } else { delete value[k]; } } } } return reviver.call(holder, key, value); } // Parsing happens in four stages. In the first stage, we replace certain // Unicode characters with escape sequences. JavaScript handles many characters // incorrectly, either silently deleting them, or treating them as line endings. cx.lastIndex = 0; if (cx.test(text)) { text = text.replace(cx, function (a) { return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4); }); } // In the second stage, we run the text against regular expressions that look // for non-JSON patterns. We are especially concerned with '()' and 'new' // because they can cause invocation, and '=' because it can cause mutation. // But just to be safe, we want to reject all unexpected forms. // We split the second stage into 4 regexp operations in order to work around // crippling inefficiencies in IE's and Safari's regexp engines. First we // replace the JSON backslash pairs with '@' (a non-JSON character). Second, we // replace all simple value tokens with ']' characters. Third, we delete all // open brackets that follow a colon or comma or that begin the text. Finally, // we look to see that the remaining characters are only whitespace or ']' or // ',' or ':' or '{' or '}'. If that is so, then the text is safe for eval. if (/^[\],:{}\s]*$/. test(text.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@'). replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']'). replace(/(?:^|:|,)(?:\s*\[)+/g, ''))) { // In the third stage we use the eval function to compile the text into a // JavaScript structure. The '{' operator is subject to a syntactic ambiguity // in JavaScript: it can begin a block or an object literal. We wrap the text // in parens to eliminate the ambiguity. j = eval('(' + text + ')'); // In the optional fourth stage, we recursively walk the new structure, passing // each name/value pair to a reviver function for possible transformation. return typeof reviver === 'function' ? walk({'': j}, '') : j; } // If the text is not JSON parseable, then a SyntaxError is thrown. throw new SyntaxError('JSON.parse'); }; } }()); es5-shim-4.4.1/tests/native.html000066400000000000000000000027741263422513500165050ustar00rootroot00000000000000 Jasmine Spec Runner es5-shim-4.4.1/tests/spec/000077500000000000000000000000001263422513500152515ustar00rootroot00000000000000es5-shim-4.4.1/tests/spec/helpers-jasmine.js000066400000000000000000000000701263422513500206720ustar00rootroot00000000000000/* globals require */ require('../helpers/h-matchers'); es5-shim-4.4.1/tests/spec/s-array.js000066400000000000000000002236461263422513500172020ustar00rootroot00000000000000/* global describe, it, expect, beforeEach, jasmine, xit */ var toStr = Object.prototype.toString; var canDistinguishSparseFromUndefined = 0 in [undefined]; // IE 6 - 8 have a bug where this returns false. var ifHasDenseUndefinedsIt = canDistinguishSparseFromUndefined ? it : xit; var undefinedIfNoSparseBug = canDistinguishSparseFromUndefined ? undefined : { valueOf: function () { return 0; } }; var hasStrictMode = (function () { 'use strict'; return !this; }()); var ifHasStrictIt = hasStrictMode ? it : xit; describe('Array', function () { var testSubject; beforeEach(function () { testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, false, 0]; delete testSubject[1]; }); var createArrayLikeFromArray = function createArrayLikeFromArray(arr) { var o = {}; Array.prototype.forEach.call(arr, function (e, i) { o[i] = e; }); o.length = arr.length; return o; }; describe('#forEach()', function () { var expected, actual; beforeEach(function () { expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true, 4: 'hej', 5: null, 6: false, 7: 0 }; actual = {}; }); it('should pass the right parameters', function () { var callback = jasmine.createSpy('callback'); var array = ['1']; array.forEach(callback); expect(callback).toHaveBeenCalledWith('1', 0, array); }); it('should not affect elements added to the array after it has begun', function () { var arr = [1, 2, 3]; var i = 0; arr.forEach(function (a) { i += 1; arr.push(a + 3); }); expect(arr).toEqual([1, 2, 3, 4, 5, 6]); expect(i).toBe(3); }); it('should set the right context when given none', function () { var context; [1].forEach(function () { context = this; }); expect(context).toBe(function () { return this; }.call()); }); it('should iterate all', function () { testSubject.forEach(function (obj, index) { actual[index] = obj; }); expect(actual).toExactlyMatch(expected); }); it('should iterate all using a context', function () { var o = { a: actual }; testSubject.forEach(function (obj, index) { this.a[index] = obj; }, o); expect(actual).toExactlyMatch(expected); }); it('should iterate all in an array-like object', function () { var ts = createArrayLikeFromArray(testSubject); Array.prototype.forEach.call(ts, function (obj, index) { actual[index] = obj; }); expect(actual).toExactlyMatch(expected); }); it('should iterate all in an array-like object using a context', function () { var ts = createArrayLikeFromArray(testSubject); var o = { a: actual }; Array.prototype.forEach.call(ts, function (obj, index) { this.a[index] = obj; }, o); expect(actual).toExactlyMatch(expected); }); describe('strings', function () { var str = 'Hello, World!'; it('should iterate all in a string', function () { actual = []; Array.prototype.forEach.call(str, function (item, index) { actual[index] = item; }); expect(actual).toExactlyMatch(str.split('')); }); it('should iterate all in a string using a context', function () { actual = []; var o = { a: actual }; Array.prototype.forEach.call(str, function (item, index) { this.a[index] = item; }, o); expect(actual).toExactlyMatch(str.split('')); }); }); it('should have a boxed object as list argument of callback', function () { var listArg; Array.prototype.forEach.call('foo', function (item, index, list) { listArg = list; }); expect(typeof listArg).toBe('object'); expect(toStr.call(listArg)).toBe('[object String]'); }); ifHasStrictIt('does not autobox the content in strict mode', function () { var context; [1].forEach(function () { 'use strict'; context = this; }, 'x'); expect(typeof context).toBe('string'); }); }); describe('#some()', function () { var actual, expected, numberOfRuns; beforeEach(function () { expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true }; actual = {}; numberOfRuns = 0; }); it('should pass the correct values along to the callback', function () { var callback = jasmine.createSpy('callback'); var array = ['1']; array.some(callback); expect(callback).toHaveBeenCalledWith('1', 0, array); }); it('should not affect elements added to the array after it has begun', function () { var arr = [1, 2, 3]; var i = 0; arr.some(function (a) { i += 1; arr.push(a + 3); return i > 3; }); expect(arr).toEqual([1, 2, 3, 4, 5, 6]); expect(i).toBe(3); }); it('should set the right context when given none', function () { var context; [1].some(function () { context = this; }); expect(context).toBe(function () { return this; }.call()); }); it('should return false if it runs to the end', function () { actual = testSubject.some(function () {}); expect(actual).toBeFalsy(); }); it('should return true if it is stopped somewhere', function () { actual = testSubject.some(function () { return true; }); expect(actual).toBeTruthy(); }); it('should return false if there are no elements', function () { actual = [].some(function () { return true; }); expect(actual).toBeFalsy(); }); it('should stop after 3 elements', function () { testSubject.some(function (obj, index) { actual[index] = obj; numberOfRuns += 1; return numberOfRuns === 3; }); expect(actual).toExactlyMatch(expected); }); it('should stop after 3 elements using a context', function () { var o = { a: actual }; testSubject.some(function (obj, index) { this.a[index] = obj; numberOfRuns += 1; return numberOfRuns === 3; }, o); expect(actual).toExactlyMatch(expected); }); it('should stop after 3 elements in an array-like object', function () { var ts = createArrayLikeFromArray(testSubject); Array.prototype.some.call(ts, function (obj, index) { actual[index] = obj; numberOfRuns += 1; return numberOfRuns === 3; }); expect(actual).toExactlyMatch(expected); }); it('should stop after 3 elements in an array-like object using a context', function () { var ts = createArrayLikeFromArray(testSubject); var o = { a: actual }; Array.prototype.some.call(ts, function (obj, index) { this.a[index] = obj; numberOfRuns += 1; return numberOfRuns === 3; }, o); expect(actual).toExactlyMatch(expected); }); it('should have a boxed object as list argument of callback', function () { var listArg; Array.prototype.some.call('foo', function (item, index, list) { listArg = list; }); expect(typeof listArg).toBe('object'); expect(toStr.call(listArg)).toBe('[object String]'); }); }); describe('#every()', function () { var actual, expected, numberOfRuns; beforeEach(function () { expected = { 0: 2, 2: undefinedIfNoSparseBug, 3: true }; actual = {}; numberOfRuns = 0; }); it('should pass the correct values along to the callback', function () { var callback = jasmine.createSpy('callback'); var array = ['1']; array.every(callback); expect(callback).toHaveBeenCalledWith('1', 0, array); }); it('should not affect elements added to the array after it has begun', function () { var arr = [1, 2, 3]; var i = 0; arr.every(function (a) { i += 1; arr.push(a + 3); return i <= 3; }); expect(arr).toEqual([1, 2, 3, 4, 5, 6]); expect(i).toBe(3); }); it('should set the right context when given none', function () { var context; [1].every(function () { context = this; }); expect(context).toBe(function () { return this; }.call()); }); it('should return true if the array is empty', function () { actual = [].every(function () { return true; }); expect(actual).toBeTruthy(); actual = [].every(function () { return false; }); expect(actual).toBeTruthy(); }); it('should return true if it runs to the end', function () { actual = [1, 2, 3].every(function () { return true; }); expect(actual).toBeTruthy(); }); it('should return false if it is stopped before the end', function () { actual = [1, 2, 3].every(function () { return false; }); expect(actual).toBeFalsy(); }); it('should return after 3 elements', function () { testSubject.every(function (obj, index) { actual[index] = obj; numberOfRuns += 1; return numberOfRuns !== 3; }); expect(actual).toExactlyMatch(expected); }); it('should stop after 3 elements using a context', function () { var o = { a: actual }; testSubject.every(function (obj, index) { this.a[index] = obj; numberOfRuns += 1; return numberOfRuns !== 3; }, o); expect(actual).toExactlyMatch(expected); }); it('should stop after 3 elements in an array-like object', function () { var ts = createArrayLikeFromArray(testSubject); Array.prototype.every.call(ts, function (obj, index) { actual[index] = obj; numberOfRuns += 1; return numberOfRuns !== 3; }); expect(actual).toExactlyMatch(expected); }); it('should stop after 3 elements in an array-like object using a context', function () { var ts = createArrayLikeFromArray(testSubject); var o = { a: actual }; Array.prototype.every.call(ts, function (obj, index) { this.a[index] = obj; numberOfRuns += 1; return numberOfRuns !== 3; }, o); expect(actual).toExactlyMatch(expected); }); it('should have a boxed object as list argument of callback', function () { var listArg; Array.prototype.every.call('foo', function (item, index, list) { listArg = list; }); expect(typeof listArg).toBe('object'); expect(toStr.call(listArg)).toBe('[object String]'); }); }); describe('#indexOf()', function () { 'use strict'; var actual, expected; beforeEach(function () { testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, false, 0]; delete testSubject[1]; }); it('should find the element', function () { expected = 4; actual = testSubject.indexOf('hej'); expect(actual).toBe(expected); }); it('should not find the element', function () { expected = -1; actual = testSubject.indexOf('mus'); expect(actual).toBe(expected); }); ifHasDenseUndefinedsIt('should find undefined as well', function () { expected = -1; actual = testSubject.indexOf(undefined); expect(actual).not.toBe(expected); }); ifHasDenseUndefinedsIt('should skip unset indexes', function () { expected = 2; actual = testSubject.indexOf(undefined); expect(actual).toBe(expected); }); it('should use a strict test', function () { actual = testSubject.indexOf(null); expect(actual).toBe(5); actual = testSubject.indexOf('2'); expect(actual).toBe(-1); }); it('should skip the first if fromIndex is set', function () { expect(testSubject.indexOf(2, 2)).toBe(6); expect(testSubject.indexOf(2, 0)).toBe(0); expect(testSubject.indexOf(2, 6)).toBe(6); }); it('should work with negative fromIndex', function () { expect(testSubject.indexOf(2, -3)).toBe(6); expect(testSubject.indexOf(2, -9)).toBe(0); }); it('should work with fromIndex being greater than the length', function () { expect(testSubject.indexOf(0, 20)).toBe(-1); }); it('should work with fromIndex being negative and greater than the length', function () { expect(testSubject.indexOf('hej', -20)).toBe(4); }); describe('Array-like', function ArrayLike() { var indexOf = Array.prototype.indexOf; var testAL; beforeEach(function beforeEach() { testAL = {}; testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, false, 0]; testSubject.forEach(function (o, i) { testAL[i] = o; }); testAL.length = testSubject.length; }); it('should find the element (array-like)', function () { expected = 4; actual = indexOf.call(testAL, 'hej'); expect(actual).toBe(expected); }); it('should not find the element (array-like)', function () { expected = -1; actual = indexOf.call(testAL, 'mus'); expect(actual).toBe(expected); }); ifHasDenseUndefinedsIt('should find undefined as well (array-like)', function () { expected = -1; actual = indexOf.call(testAL, undefined); expect(actual).not.toBe(expected); }); ifHasDenseUndefinedsIt('should skip unset indexes (array-like)', function () { expected = 2; actual = indexOf.call(testAL, undefined); expect(actual).toBe(expected); }); it('should use a strict test (array-like)', function () { actual = Array.prototype.indexOf.call(testAL, null); expect(actual).toBe(5); actual = Array.prototype.indexOf.call(testAL, '2'); expect(actual).toBe(-1); }); it('should skip the first if fromIndex is set (array-like)', function () { expect(indexOf.call(testAL, 2, 2)).toBe(6); expect(indexOf.call(testAL, 2, 0)).toBe(0); expect(indexOf.call(testAL, 2, 6)).toBe(6); }); it('should work with negative fromIndex (array-like)', function () { expect(indexOf.call(testAL, 2, -3)).toBe(6); expect(indexOf.call(testAL, 2, -9)).toBe(0); }); it('should work with fromIndex being greater than the length (array-like)', function () { expect(indexOf.call(testAL, 0, 20)).toBe(-1); }); it('should work with fromIndex being negative and greater than the length (array-like)', function () { expect(indexOf.call(testAL, 'hej', -20)).toBe(4); }); }); }); describe('#lastIndexOf()', function () { 'use strict'; var actual, expected; beforeEach(function () { testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', null, 2, 3, false, 0]; delete testSubject[1]; delete testSubject[7]; }); describe('Array', function () { it('should find the element', function () { expected = 4; actual = testSubject.lastIndexOf('hej'); expect(actual).toBe(expected); }); it('should not find the element', function () { expected = -1; actual = testSubject.lastIndexOf('mus'); expect(actual).toBe(expected); }); ifHasDenseUndefinedsIt('should find undefined as well', function () { expected = -1; actual = testSubject.lastIndexOf(undefined); expect(actual).not.toBe(expected); }); ifHasDenseUndefinedsIt('should skip unset indexes', function () { expected = 2; actual = testSubject.lastIndexOf(undefined); expect(actual).toBe(expected); }); it('should use a strict test', function () { actual = testSubject.lastIndexOf(null); expect(actual).toBe(5); actual = testSubject.lastIndexOf('2'); expect(actual).toBe(-1); }); it('should skip the first if fromIndex is set', function () { expect(testSubject.lastIndexOf(2, 2)).toBe(0); expect(testSubject.lastIndexOf(2, 0)).toBe(0); expect(testSubject.lastIndexOf(2, 6)).toBe(6); }); it('should work with negative fromIndex', function () { expect(testSubject.lastIndexOf(2, -3)).toBe(6); expect(testSubject.lastIndexOf(2, -9)).toBe(0); }); it('should work with fromIndex being greater than the length', function () { expect(testSubject.lastIndexOf(2, 20)).toBe(6); }); it('should work with fromIndex being negative and greater than the length', function () { expect(testSubject.lastIndexOf(2, -20)).toBe(-1); }); }); describe('Array like', function () { var lastIndexOf = Array.prototype.lastIndexOf; var testAL; beforeEach(function () { testAL = {}; testSubject.forEach(function (o, i) { testAL[i] = o; }); testAL.length = testSubject.length; }); it('should find the element (array-like)', function () { expected = 4; actual = lastIndexOf.call(testAL, 'hej'); expect(actual).toBe(expected); }); it('should not find the element (array-like)', function () { expected = -1; actual = lastIndexOf.call(testAL, 'mus'); expect(actual).toBe(expected); }); ifHasDenseUndefinedsIt('should find undefined as well (array-like)', function () { expected = -1; actual = lastIndexOf.call(testAL, undefined); expect(actual).not.toBe(expected); }); ifHasDenseUndefinedsIt('should skip unset indexes (array-like)', function () { expected = 2; actual = lastIndexOf.call(testAL, undefined); expect(actual).toBe(expected); }); it('should use a strict test (array-like)', function () { actual = lastIndexOf.call(testAL, null); expect(actual).toBe(5); actual = lastIndexOf.call(testAL, '2'); expect(actual).toBe(-1); }); it('should skip the first if fromIndex is set', function () { expect(lastIndexOf.call(testAL, 2, 2)).toBe(0); expect(lastIndexOf.call(testAL, 2, 0)).toBe(0); expect(lastIndexOf.call(testAL, 2, 6)).toBe(6); }); it('should work with negative fromIndex', function () { expect(lastIndexOf.call(testAL, 2, -3)).toBe(6); expect(lastIndexOf.call(testAL, 2, -9)).toBe(0); }); it('should work with fromIndex being greater than the length', function () { expect(lastIndexOf.call(testAL, 2, 20)).toBe(6); }); it('should work with fromIndex being negative and greater than the length', function () { expect(lastIndexOf.call(testAL, 2, -20)).toBe(-1); }); }); }); describe('#filter()', function () { var filteredArray; var callback = function callback(o, i) { return i !== 3 && i !== 5; }; beforeEach(function () { testSubject = [2, 3, undefinedIfNoSparseBug, true, 'hej', 3, null, false, 0]; delete testSubject[1]; filteredArray = [2, undefinedIfNoSparseBug, 'hej', null, false, 0]; }); describe('Array object', function () { it('should call the callback with the proper arguments', function () { var predicate = jasmine.createSpy('predicate'); var arr = ['1']; arr.filter(predicate); expect(predicate).toHaveBeenCalledWith('1', 0, arr); }); it('should not affect elements added to the array after it has begun', function () { var arr = [1, 2, 3]; var i = 0; arr.filter(function (a) { i += 1; if (i <= 4) { arr.push(a + 3); } return true; }); expect(arr).toEqual([1, 2, 3, 4, 5, 6]); expect(i).toBe(3); }); ifHasDenseUndefinedsIt('should skip unset values', function () { var passedValues = {}; testSubject = [1, 2, 3, 4]; delete testSubject[1]; testSubject.filter(function (o, i) { passedValues[i] = o; return true; }); expect(passedValues).toExactlyMatch(testSubject); }); it('should pass the right context to the filter', function () { var passedValues = {}; testSubject = [1, 2, 3, 4]; delete testSubject[1]; testSubject.filter(function (o, i) { this[i] = o; return true; }, passedValues); expect(passedValues).toExactlyMatch(testSubject); }); it('should set the right context when given none', function () { var context; [1].filter(function () { context = this; }); expect(context).toBe(function () { return this; }.call()); }); it('should remove only the values for which the callback returns false', function () { var result = testSubject.filter(callback); expect(result).toExactlyMatch(filteredArray); }); it('should leave the original array untouched', function () { var copy = testSubject.slice(); testSubject.filter(callback); expect(testSubject).toExactlyMatch(copy); }); it('should not be affected by same-index mutation', function () { var results = [1, 2, 3].filter(function (value, index, array) { array[index] = 'a'; return true; }); expect(results).toEqual([1, 2, 3]); }); }); describe('Array like', function () { beforeEach(function () { testSubject = createArrayLikeFromArray(testSubject); }); it('should call the predicate with the proper arguments', function () { var predicate = jasmine.createSpy('predicate'); var arr = createArrayLikeFromArray(['1']); Array.prototype.filter.call(arr, predicate); expect(predicate).toHaveBeenCalledWith('1', 0, arr); }); it('should not affect elements added to the array after it has begun', function () { var arr = createArrayLikeFromArray([1, 2, 3]); var i = 0; Array.prototype.filter.call(arr, function (a) { i += 1; if (i <= 4) { arr[i + 2] = a + 3; arr.length += 1; } return true; }); expect(Array.prototype.slice.call(arr)).toEqual([1, 2, 3, 4, 5, 6]); expect(i).toBe(3); }); it('should skip non-set values', function () { var passedValues = createArrayLikeFromArray([]); testSubject = createArrayLikeFromArray([1, 2, 3, 4]); delete testSubject[1]; Array.prototype.filter.call(testSubject, function (o, i) { passedValues[i] = o; passedValues.length = i + 1; return true; }); expect(passedValues).toEqual(testSubject); }); it('should set the right context when given none', function () { var context; Array.prototype.filter.call(createArrayLikeFromArray([1]), function () { context = this; }, undefined); expect(context).toBe(function () { return this; }.call()); }); it('should pass the right context to the filter', function () { var passedValues = {}; testSubject = createArrayLikeFromArray([1, 2, 3, 4]); delete testSubject[1]; Array.prototype.filter.call(testSubject, function (o, i) { this[i] = o; this.length = i + 1; return true; }, passedValues); expect(passedValues).toEqual(testSubject); }); it('should remove only the values for which the callback returns false', function () { var result = Array.prototype.filter.call(testSubject, callback); expect(result).toExactlyMatch(filteredArray); }); it('should leave the original array untouched', function () { var copy = createArrayLikeFromArray(testSubject); Array.prototype.filter.call(testSubject, callback); expect(testSubject).toExactlyMatch(copy); }); }); it('should have a boxed object as list argument of callback', function () { var actual; Array.prototype.filter.call('foo', function (item, index, list) { actual = list; }); expect(typeof actual).toBe('object'); expect(toStr.call(actual)).toBe('[object String]'); }); }); describe('#map()', function () { var callback; beforeEach(function () { var i = 0; callback = function () { return i++; }; }); describe('Array object', function () { it('should call mapper with the right parameters', function () { var mapper = jasmine.createSpy('mapper'); var array = [1]; array.map(mapper); expect(mapper).toHaveBeenCalledWith(1, 0, array); }); it('should set the context correctly', function () { var context = {}; testSubject.map(function (o, i) { this[i] = o; }, context); expect(context).toExactlyMatch(testSubject); }); it('should set the right context when given none', function () { var context; [1].map(function () { context = this; }); expect(context).toBe(function () { return this; }.call()); }); it('should not change the array it is called on', function () { var copy = testSubject.slice(); testSubject.map(callback); expect(testSubject).toExactlyMatch(copy); }); it('should only run for the number of objects in the array when it started', function () { var arr = [1, 2, 3]; var i = 0; arr.map(function (o) { arr.push(o + 3); i += 1; return o; }); expect(arr).toExactlyMatch([1, 2, 3, 4, 5, 6]); expect(i).toBe(3); }); it('should properly translate the values as according to the callback', function () { var result = testSubject.map(callback); var expected = [0, 0, 1, 2, 3, 4, 5, 6]; delete expected[1]; expect(result).toExactlyMatch(expected); }); it('should skip non-existing values', function () { var array = [1, 2, 3, 4]; var i = 0; delete array[2]; array.map(function () { i += 1; }); expect(i).toBe(3); }); }); describe('Array-like', function () { beforeEach(function () { testSubject = createArrayLikeFromArray(testSubject); }); it('should call mapper with the right parameters', function () { var mapper = jasmine.createSpy('mapper'); var array = createArrayLikeFromArray([1]); Array.prototype.map.call(array, mapper); expect(mapper).toHaveBeenCalledWith(1, 0, array); }); it('should set the context correctly', function () { var context = {}; Array.prototype.map.call(testSubject, function (o, i) { this[i] = o; this.length = i + 1; }, context); expect(context).toEqual(testSubject); }); it('should set the right context when given none', function () { var context; Array.prototype.map.call(createArrayLikeFromArray([1]), function () { context = this; }); expect(context).toBe(function () { return this; }.call()); }); it('should not change the array it is called on', function () { var copy = createArrayLikeFromArray(testSubject); Array.prototype.map.call(testSubject, callback); expect(testSubject).toExactlyMatch(copy); }); it('should only run for the number of objects in the array when it started', function () { var arr = createArrayLikeFromArray([1, 2, 3]); var i = 0; Array.prototype.map.call(arr, function (o) { Array.prototype.push.call(arr, o + 3); i += 1; return o; }); expect(Array.prototype.slice.call(arr)).toEqual([1, 2, 3, 4, 5, 6]); expect(i).toBe(3); }); it('should properly translate the values as according to the callback', function () { var result = Array.prototype.map.call(testSubject, callback); var expected = [0, 0, 1, 2, 3, 4, 5, 6]; delete expected[1]; expect(result).toExactlyMatch(expected); }); it('should skip non-existing values', function () { var array = createArrayLikeFromArray([1, 2, 3, 4]); var i = 0; delete array[2]; Array.prototype.map.call(array, function () { i += 1; }); expect(i).toBe(3); }); }); it('should have a boxed object as list argument of callback', function () { var actual; Array.prototype.map.call('foo', function (item, index, list) { actual = list; }); expect(typeof actual).toBe('object'); expect(toStr.call(actual)).toBe('[object String]'); }); }); describe('#reduce()', function () { beforeEach(function () { testSubject = [1, 2, 3]; }); describe('Array', function () { it('should pass the correct arguments to the callback', function () { var spy = jasmine.createSpy().andReturn(0); testSubject.reduce(spy); expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]); }); it('should start with the right initialValue', function () { var spy = jasmine.createSpy().andReturn(0); testSubject.reduce(spy, 0); expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]); }); it('should not affect elements added to the array after it has begun', function () { var arr = [1, 2, 3]; var i = 0; arr.reduce(function (a, b) { i += 1; if (i <= 4) { arr.push(a + 3); } return b; }); expect(arr).toEqual([1, 2, 3, 4, 5]); expect(i).toBe(2); }); it('should work as expected for empty arrays', function () { var spy = jasmine.createSpy(); expect(function () { [].reduce(spy); }).toThrow(); expect(spy).not.toHaveBeenCalled(); }); it('should throw correctly if no callback is given', function () { expect(function () { testSubject.reduce(); }).toThrow(); }); it('should return the expected result', function () { expect(testSubject.reduce(function (a, b) { return String(a || '') + String(b || ''); })).toBe(testSubject.join('')); }); it('should not directly affect the passed array', function () { var copy = testSubject.slice(); testSubject.reduce(function (a, b) { return a + b; }); expect(testSubject).toEqual(copy); }); it('should skip non-set values', function () { delete testSubject[1]; var visited = {}; testSubject.reduce(function (a, b) { if (a) { visited[a] = true; } if (b) { visited[b] = true; } return 0; }); expect(visited).toEqual({ 1: true, 3: true }); }); it('should have the right length', function () { expect(testSubject.reduce.length).toBe(1); }); }); describe('Array-like objects', function () { beforeEach(function () { testSubject = createArrayLikeFromArray(testSubject); testSubject.reduce = Array.prototype.reduce; }); it('should pass the correct arguments to the callback', function () { var spy = jasmine.createSpy().andReturn(0); testSubject.reduce(spy); expect(spy.calls[0].args).toExactlyMatch([1, 2, 1, testSubject]); }); it('should start with the right initialValue', function () { var spy = jasmine.createSpy().andReturn(0); testSubject.reduce(spy, 0); expect(spy.calls[0].args).toExactlyMatch([0, 1, 0, testSubject]); }); it('should not affect elements added to the array after it has begun', function () { var arr = createArrayLikeFromArray([1, 2, 3]); var i = 0; Array.prototype.reduce.call(arr, function (a, b) { i += 1; if (i <= 4) { arr[i + 2] = a + 3; } return b; }); expect(arr).toEqual({ 0: 1, 1: 2, 2: 3, 3: 4, 4: 5, length: 3 }); expect(i).toBe(2); }); it('should work as expected for empty arrays', function () { var spy = jasmine.createSpy(); expect(function () { Array.prototype.reduce.call({ length: 0 }, spy); }).toThrow(); expect(spy).not.toHaveBeenCalled(); }); it('should throw correctly if no callback is given', function () { expect(function () { testSubject.reduce(); }).toThrow(); }); it('should return the expected result', function () { expect(testSubject.reduce(function (a, b) { return String(a || '') + String(b || ''); })).toBe('123'); }); it('should not directly affect the passed array', function () { var copy = createArrayLikeFromArray(testSubject); testSubject.reduce(function (a, b) { return a + b; }); delete testSubject.reduce; expect(testSubject).toEqual(copy); }); it('should skip non-set values', function () { delete testSubject[1]; var visited = {}; testSubject.reduce(function (a, b) { if (a) { visited[a] = true; } if (b) { visited[b] = true; } return 0; }); expect(visited).toEqual({ 1: true, 3: true }); }); it('should have the right length', function () { expect(testSubject.reduce.length).toBe(1); }); }); it('should have a boxed object as list argument of callback', function () { var actual; Array.prototype.reduce.call('foo', function (accumulator, item, index, list) { actual = list; }); expect(typeof actual).toBe('object'); expect(toStr.call(actual)).toBe('[object String]'); }); }); describe('#reduceRight()', function () { beforeEach(function () { testSubject = [1, 2, 3]; }); describe('Array', function () { it('should pass the correct arguments to the callback', function () { var spy = jasmine.createSpy().andReturn(0); testSubject.reduceRight(spy); expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]); }); it('should start with the right initialValue', function () { var spy = jasmine.createSpy().andReturn(0); testSubject.reduceRight(spy, 0); expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]); }); it('should not affect elements added to the array after it has begun', function () { var arr = [1, 2, 3]; var i = 0; arr.reduceRight(function (a, b) { i += 1; if (i <= 4) { arr.push(a + 3); } return b; }); expect(arr).toEqual([1, 2, 3, 6, 5]); expect(i).toBe(2); }); it('should work as expected for empty arrays', function () { var spy = jasmine.createSpy(); expect(function () { [].reduceRight(spy); }).toThrow(); expect(spy).not.toHaveBeenCalled(); }); it('should work as expected for empty arrays with an initial value', function () { var spy = jasmine.createSpy(); var result; result = [].reduceRight(spy, ''); expect(spy).not.toHaveBeenCalled(); expect(result).toBe(''); }); it('should throw correctly if no callback is given', function () { expect(function () { testSubject.reduceRight(); }).toThrow(); }); it('should return the expected result', function () { expect(testSubject.reduceRight(function (a, b) { return String(a || '') + String(b || ''); })).toBe('321'); }); it('should not directly affect the passed array', function () { var copy = testSubject.slice(); testSubject.reduceRight(function (a, b) { return a + b; }); expect(testSubject).toEqual(copy); }); it('should skip non-set values', function () { delete testSubject[1]; var visited = {}; testSubject.reduceRight(function (a, b) { if (a) { visited[a] = true; } if (b) { visited[b] = true; } return 0; }); expect(visited).toEqual({ 1: true, 3: true }); }); it('should have the right length', function () { expect(testSubject.reduceRight.length).toBe(1); }); }); describe('Array-like objects', function () { beforeEach(function () { testSubject = createArrayLikeFromArray(testSubject); testSubject.reduceRight = Array.prototype.reduceRight; }); it('should pass the correct arguments to the callback', function () { var spy = jasmine.createSpy().andReturn(0); testSubject.reduceRight(spy); expect(spy.calls[0].args).toExactlyMatch([3, 2, 1, testSubject]); }); it('should start with the right initialValue', function () { var spy = jasmine.createSpy().andReturn(0); testSubject.reduceRight(spy, 0); expect(spy.calls[0].args).toExactlyMatch([0, 3, 2, testSubject]); }); it('should not affect elements added to the array after it has begun', function () { var arr = createArrayLikeFromArray([1, 2, 3]); var i = 0; Array.prototype.reduceRight.call(arr, function (a, b) { i += 1; if (i <= 4) { arr[i + 2] = a + 3; } return b; }); expect(arr).toEqual({ 0: 1, 1: 2, 2: 3, 3: 6, 4: 5, length: 3 // does not get updated on property assignment }); expect(i).toBe(2); }); it('should work as expected for empty arrays', function () { var spy = jasmine.createSpy(); expect(function () { Array.prototype.reduceRight.call({ length: 0 }, spy); }).toThrow(); expect(spy).not.toHaveBeenCalled(); }); it('should throw correctly if no callback is given', function () { expect(function () { testSubject.reduceRight(); }).toThrow(); }); it('should return the expected result', function () { expect(testSubject.reduceRight(function (a, b) { return String(a || '') + String(b || ''); })).toBe('321'); }); it('should not directly affect the passed array', function () { var copy = createArrayLikeFromArray(testSubject); testSubject.reduceRight(function (a, b) { return a + b; }); delete testSubject.reduceRight; expect(testSubject).toEqual(copy); }); it('should skip non-set values', function () { delete testSubject[1]; var visited = {}; testSubject.reduceRight(function (a, b) { if (a) { visited[a] = true; } if (b) { visited[b] = true; } return 0; }); expect(visited).toEqual({ 1: true, 3: true }); }); it('should have the right length', function () { expect(testSubject.reduceRight.length).toBe(1); }); }); it('should have a boxed object as list argument of callback', function () { var actual; Array.prototype.reduceRight.call('foo', function (accumulator, item, index, list) { actual = list; }); expect(typeof actual).toBe('object'); expect(toStr.call(actual)).toBe('[object String]'); }); }); describe('.isArray()', function () { it('should be true for Array', function () { expect(Array.isArray([])).toBe(true); }); it('should be false for primitives', function () { var primitives = [ 'foo', true, false, 42, 0, -0, NaN, Infinity, -Infinity ]; primitives.forEach(function (v) { expect(Array.isArray(v)).toBe(false); }); }); it('should fail for other objects', function () { var objects = [ {}, /foo/, arguments ]; if (Object.create) { objects.push(Object.create(null)); } objects.forEach(function (v) { expect(Array.isArray(v)).toBe(false); }); }); /* globals document */ if (typeof document !== 'undefined') { it('should be false for an HTML element', function () { var el = document.getElementsByTagName('div'); expect(Array.isArray(el)).toBe(false); }); } }); describe('#shift()', function () { it('works on arrays', function () { var arr = [1, 2]; var result = arr.shift(); expect(result).toBe(1); expect(arr.length).toBe(1); expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true); expect(Object.prototype.hasOwnProperty.call(arr, 1)).toBe(false); expect(arr[0]).toBe(2); expect(arr[1]).toBeUndefined(); }); it('is generic', function () { var obj = { 0: 1, 1: 2, length: 2 }; var result = Array.prototype.shift.call(obj); expect(result).toBe(1); expect(obj.length).toBe(1); expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true); expect(Object.prototype.hasOwnProperty.call(obj, 1)).toBe(false); expect(obj[0]).toBe(2); expect(obj[1]).toBeUndefined(); }); }); describe('#unshift()', function () { it('should return length', function () { expect([].unshift(0)).toBe(1); }); it('works on arrays', function () { var arr = [1]; var result = arr.unshift(undefined); expect(result).toBe(2); expect(arr.length).toBe(2); expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true); expect(Object.prototype.hasOwnProperty.call(arr, 1)).toBe(true); expect(arr[0]).toBeUndefined(); expect(arr[1]).toBe(1); }); it('is generic', function () { var obj = { 0: 1, length: 1 }; var result = Array.prototype.unshift.call(obj, undefined); expect(result).toBe(2); expect(obj.length).toBe(2); expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true); expect(Object.prototype.hasOwnProperty.call(obj, 1)).toBe(true); expect(obj[0]).toBeUndefined(); expect(obj[1]).toBe(1); }); }); describe('#splice()', function () { var b = ['b']; var a = [1, 'a', b]; var test; var makeArray = function (l, givenPrefix) { var prefix = givenPrefix || ''; var length = l; var arr = []; while (length--) { arr.unshift(prefix + Array(length + 1).join(' ') + length); } return arr; }; beforeEach(function () { test = a.slice(0); }); it('has the right length', function () { expect(Array.prototype.splice.length).toBe(2); }); /* This test is disabled, because ES6 normalizes actual * browser behavior, contradicting ES5. */ xit('treats undefined deleteCount as 0', function () { expect(test.splice(0).length).toBe(0); expect(test.splice(0)).toEqual(test.splice(0, 0)); }); it('basic implementation test 1', function () { expect(test.splice(0, 0)).toEqual([]); }); it('basic implementation test 2', function () { test.splice(0, 2); expect(test).toEqual([b]); }); it('should return right result 1', function () { var array = []; array.splice(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20); array.splice(1, 0, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26'); array.splice(5, 0, 'XXX'); expect(array).toEqual([1, 'F1', 'F2', 'F3', 'F4', 'XXX', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]); }); it('should return right result 2', function () { var array = makeArray(6); array.splice(array.length - 1, 1, ''); array.splice(0, 1, 1, 2, 3, 4); array.splice(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45); array.splice(4, 0, '99999999999999'); expect(array).toEqual([1, 2, 3, 4, '99999999999999', 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 1, 2, 3, 4, ' 1', ' 2', ' 3', ' 4', '']); }); it('should return right result 3', function () { var array = [1, 2, 3]; array.splice(0, array.length); array.splice(0, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10); array.splice(1, 1, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26'); array.splice(5, 1, 'YYY', 'XXX'); array.splice(0, 1); array.splice(0, 2); array.pop(); array.push.apply(array, makeArray(10, '-')); array.splice(array.length - 2, 10); array.splice(); array.splice(1, 1, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9); array.splice(1, 1, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 5, 6, 7, 8); array.splice(30, 10); array.splice(30, 1); array.splice(30, 0); array.splice(2, 5, 1, 2, 3, 'P', 'LLL', 'CCC', 'YYY', 'XXX'); array.push(1, 2, 3, 4, 5, 6); array.splice(1, 6, 1, 2, 3, 4, 5, 6, 7, 8, 9, 4, 5, 6, 7, 8, 9); array.splice(3, 7); array.unshift(7, 8, 9, 10, 11); array.pop(); array.splice(5, 2); array.pop(); array.unshift.apply(array, makeArray(8, '~')); array.pop(); array.splice(3, 1, 'F1', 'F2', 'F3', 'F4', 'F5', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 5, 6, 7, 8); array.splice(4, 5, 'P', 'LLL', 'CCC', 'YYY', 'XXX'); expect(array).toEqual(['~0', '~ 1', '~ 2', 'F1', 'P', 'LLL', 'CCC', 'YYY', 'XXX', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 5, 6, 7, 8, '~ 4', '~ 5', '~ 6', '~ 7', 7, 8, 9, 10, 11, 2, 4, 5, 6, 7, 8, 9, 'CCC', 'YYY', 'XXX', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 1, 23, 4, 9, 10, 1, 2, 3, 4, 5, 6, 7, 8, 9, 'YYY', 'XXX', 'F6', 'F7', 'F8', 'F9', 'F10', 'F11', 'F12', 'F13', 'F14', 'F15', 'F16', 'F17', 'F18', 'F19', 'F20', 'F21', 'F22', 'F23', 'F24', 'F25', 'F26', 3, 4, 5, 6, 7, 8, 9, '-0', '- 1', '- 2', '- 3', '- 4', '- 5', '- 6', '- 7', 1, 2, 3]); }); it('should do nothing if method called with no arguments', function () { expect(test.splice()).toEqual([]); expect(test).toEqual(a); }); it('should set first argument to 0 if first argument is set but undefined', function () { var test2 = test.slice(0); expect(test.splice(void 0, 2)).toEqual(test2.splice(0, 2)); expect(test).toEqual(test2); }); it('should work with objects - adding 1', function () { var obj = {}; Array.prototype.splice.call(obj, 0, 0, 1, 2, 3); expect(obj.length).toBe(3); }); it('should work with objects - adding 2', function () { var obj = { 0: 1, length: 1 }; Array.prototype.splice.call(obj, 1, 0, 2, 3); expect(obj.length).toBe(3); }); it('should work with objects - removing', function () { var obj = { 0: 1, 1: 2, 2: 3, length: 3 }; Array.prototype.splice.call(obj, 0, 3); expect(obj.length).toBe(0); }); it('should work with objects - replacing', function () { var obj = { 0: 99, length: 1 }; Array.prototype.splice.call(obj, 0, 1, 1, 2, 3); expect(obj.length).toBe(3); expect(obj[0]).toBe(1); }); ifHasDenseUndefinedsIt('should not break on sparse arrays in Opera', function () { // test from https://github.com/wikimedia/VisualEditor/blob/d468b00311e69c2095b9da360c5745153342a5c3/src/ve.utils.js#L182-L196 var n = 256; var arr = []; arr[n] = 'a'; arr.splice(n + 1, 0, 'b'); expect(arr[n]).toBe('a'); }); ifHasDenseUndefinedsIt('should not break on sparse arrays in Safari 7/8', function () { // test from https://github.com/wikimedia/VisualEditor/blob/d468b00311e69c2095b9da360c5745153342a5c3/src/ve.utils.js#L182-L196 var justFine = new Array(1e5 - 1); justFine[10] = 'x'; var tooBig = new Array(1e5); tooBig[8] = 'x'; justFine.splice(1, 1); expect(8 in justFine).toBe(false); expect(justFine.indexOf('x')).toBe(9); tooBig.splice(1, 1); expect(6 in tooBig).toBe(false); expect(tooBig.indexOf('x')).toBe(7); }); }); describe('#join()', function () { it('defaults to a comma separator when none is provided', function () { expect([1, 2].join()).toBe('1,2'); }); it('defaults to a comma separator when undefined is provided', function () { expect([1, 2].join(undefined)).toBe('1,2'); }); it('works, extended', function () { expect([].join()).toBe(''); expect([undefined].join()).toBe(''); expect([undefined, undefined].join()).toBe(','); expect([null, null].join()).toBe(','); expect([undefined, undefined].join('|')).toBe('|'); expect([null, null].join('|')).toBe('|'); expect([1, 2, 3].join('|')).toBe('1|2|3'); expect([1, 2, 3].join(null)).toBe('1null2null3'); expect([1, 2, 3].join({})).toBe('1[object Object]2[object Object]3'); expect([1, 2, 3].join('')).toBe('123'); }); it('is generic', function () { var obj = { 0: 1, 1: 2, 2: 3, 3: 4, length: 3 }; expect(Array.prototype.join.call(obj, ',')).toBe('1,2,3'); }); it('works with a string literal', function () { var str = '123'; expect(Array.prototype.join.call(str, ',')).toBe('1,2,3'); }); it('works with `arguments`', function () { var args = (function () { return arguments; }(1, 2, 3)); expect(Array.prototype.join.call(args, ',')).toBe('1,2,3'); }); }); describe('#push()', function () { it('works on arrays', function () { var arr = []; var result = arr.push(undefined); expect(result).toBe(1); expect(arr.length).toBe(1); expect(Object.prototype.hasOwnProperty.call(arr, 0)).toBe(true); expect(arr[0]).toBeUndefined(); }); it('is generic', function () { var obj = {}; var result = Array.prototype.push.call(obj, undefined); expect(result).toBe(1); expect(obj.length).toBe(1); expect(Object.prototype.hasOwnProperty.call(obj, 0)).toBe(true); expect(obj[0]).toBeUndefined(); }); }); describe('#pop()', function () { it('works on arrays', function () { var arr = [1, 2, 3]; var result = arr.pop(); expect(result).toBe(3); expect(arr.length).toBe(2); expect(Object.prototype.hasOwnProperty.call(arr, 2)).toBe(false); expect(arr[2]).toBeUndefined(); }); it('is generic', function () { var obj = { 0: 1, 1: 2, 2: 3, length: 3 }; var result = Array.prototype.pop.call(obj); expect(result).toBe(3); expect(obj.length).toBe(2); expect(Object.prototype.hasOwnProperty.call(obj, 2)).toBe(false); expect(obj[2]).toBeUndefined(); }); }); describe('#slice()', function () { it('works on arrays', function () { var arr = [1, 2, 3, 4]; var result = arr.slice(1, 3); expect(result).toEqual([2, 3]); }); it('is generic', function () { var obj = { 0: 1, 1: 2, 2: 3, 3: 4, length: 4 }; var result = Array.prototype.slice.call(obj, 1, 3); expect(result).toEqual([2, 3]); }); it('works with `arguments`', function () { var obj = (function () { return arguments; }(1, 2, 3, 4)); var result = Array.prototype.slice.call(obj, 1, 3); expect(result).toEqual([2, 3]); }); it('boxed string access', function () { var obj = '1234'; var result = Array.prototype.slice.call(obj, 1, 3); expect(result).toEqual(['2', '3']); }); }); describe('#sort()', function () { describe('usage', function () { it('requires a function or undefined as first argument', function () { var actual = [1, 2]; expect(actual.sort()).toBe(actual); expect(actual.sort(undefined)).toBe(actual); expect(actual.sort(function () { return 0; })).toBe(actual); }); it('requires a non-function or non-undefined to throw a `TypeError`', function () { expect(function () { [1, 2].sort(null); }).toThrow(); expect(function () { [1, 2].sort(1); }).toThrow(); expect(function () { [1, 2].sort(''); }).toThrow(); expect(function () { [1, 2].sort(true); }).toThrow(); expect(function () { [1, 2].sort({}); }).toThrow(); expect(function () { [1, 2].sort([]); }).toThrow(); expect(function () { [1, 2].sort(new Date()); }).toThrow(); expect(function () { [1, 2].sort(/pattern/); }).toThrow(); }); }); describe('ascending', function () { it('[5,2,4,6,1,3] should result in [1,2,3,4,5,6]', function () { var actual = [5, 2, 4, 6, 1, 3]; var expected = [1, 2, 3, 4, 5, 6]; actual.sort(); expect(actual).toEqual(expected); }); it('[5,2,2,6,1,3] should result in [1,2,2,3,5,6]', function () { var actual = [5, 2, 2, 6, 1, 3]; var expected = [1, 2, 2, 3, 5, 6]; actual.sort(); expect(actual).toEqual(expected); }); it('[0,0,0,0,0,1] should result in [0,0,0,0,0,1]', function () { var actual = [0, 0, 0, 0, 0, 1]; var expected = [0, 0, 0, 0, 0, 1]; actual.sort(); expect(actual).toEqual(expected); }); it('[0,0,0,0,0,-1] should result in [-1,0,0,0,0,0]', function () { var actual = [0, 0, 0, 0, 0, -1]; var expected = [-1, 0, 0, 0, 0, 0]; actual.sort(); expect(actual).toEqual(expected); }); it('[f,e,d,a,c,b] should result in [a,b,c,d,e,f]', function () { var actual = ['f', 'e', 'd', 'a', 'c', 'b']; var expected = ['a', 'b', 'c', 'd', 'e', 'f']; actual.sort(); expect(actual).toEqual(expected); }); it('[f,e,d,,,,a,c,b] should result in [a,b,c,d,e,f,,,]', function () { var actual = ['f', 'e', 'd', 1, 2, 'a', 'c', 'b']; delete actual[3]; delete actual[4]; var expected = ['a', 'b', 'c', 'd', 'e', 'f']; expected.length = 8; actual.sort(); expect(actual).toEqual(expected); }); it('[f,e,d,,null,,a,c,b] should result in [a,b,c,d,e,f,null,,,]', function () { var actual = ['f', 'e', 'd', 1, null, 2, 'a', 'c', 'b']; delete actual[3]; delete actual[5]; var expected = ['a', 'b', 'c', 'd', 'e', 'f', null]; expected.length = 9; actual.sort(); expect(actual).toEqual(expected); }); it('[f,e,d,,null,undefined,a,c,b] should result in [a,b,c,d,e,f,null,undefined,,]', function () { var actual = ['f', 'e', 'd', 1, null, undefined, 'a', 'c', 'b']; delete actual[3]; var expected = ['a', 'b', 'c', 'd', 'e', 'f', null, undefined]; expected.length = 9; actual.sort(); expect(actual).toEqual(expected); }); it('[] should result in []', function () { var actual = []; var expected = []; actual.sort(); expect(actual).toEqual(expected); }); it('[1] should result in [1]', function () { var actual = [1]; var expected = [1]; actual.sort(); expect(actual).toEqual(expected); }); it('result should find only greater or equal values', function () { var actual = []; var i; for (i = 0; i < 100; i += 1) { actual.push(('00' + (Math.random() * 100).toFixed(0)).slice(-3)); } actual.sort(); for (i = 0; i < actual.length - 1; i += 1) { expect(actual[i] <= actual[i + 1]).toBe(true); } }); }); describe('descending', function () { var descending = function (left, right) { var leftS = String(left); var rightS = String(right); if (leftS === rightS) { return +0; } if (leftS < rightS) { return 1; } return -1; }; it('[5,2,4,6,1,3] should result in [6,5,4,3,2,1]', function () { var actual = [5, 2, 4, 6, 1, 3]; var expected = [6, 5, 4, 3, 2, 1]; actual.sort(descending); expect(actual).toEqual(expected); }); it('[5,2,2,6,1,3] should result in [6,5,4,2,2,1]', function () { var actual = [5, 2, 2, 6, 1, 3]; var expected = [6, 5, 3, 2, 2, 1]; actual.sort(descending); expect(actual).toEqual(expected); }); it('[0,0,0,0,0,1] should result in [1,0,0,0,0,0]', function () { var actual = [0, 0, 0, 0, 0, 1]; var expected = [1, 0, 0, 0, 0, 0]; actual.sort(descending); expect(actual).toEqual(expected); }); it('[0,0,0,0,0,-1] should result in [0,0,0,0,0,-1]', function () { var actual = [0, 0, 0, 0, 0, -1]; var expected = [0, 0, 0, 0, 0, -1]; actual.sort(descending); expect(actual).toEqual(expected); }); it('[f,e,d,a,c,b] should result in [f,e,d,c,b,a]', function () { var actual = ['f', 'e', 'd', 'a', 'c', 'b']; var expected = ['f', 'e', 'd', 'c', 'b', 'a']; actual.sort(descending); expect(actual).toEqual(expected); }); it('[f,e,d,,,a,c,b] should result in [f,e,d,c,b,a,,,]', function () { var actual = ['f', 'e', 'd', 1, 2, 'a', 'c', 'b']; delete actual[3]; delete actual[4]; var expected = ['f', 'e', 'd', 'c', 'b', 'a']; expected.length = 8; actual.sort(descending); expect(actual).toEqual(expected); }); it('[f,e,d,,null,,a,c,b] should result in [null,f,e,d,c,b,a,,,]', function () { var actual = ['f', 'e', 'd', 1, null, 2, 'a', 'c', 'b']; delete actual[3]; delete actual[5]; var expected = [null, 'f', 'e', 'd', 'c', 'b', 'a']; expected.length = 9; actual.sort(descending); expect(actual).toEqual(expected); }); it('[f,e,d,undefined,null,,a,c,b] should result in [null,f,e,d,c,b,a,undefined,,]', function () { var actual = ['f', 'e', 'd', undefined, null, 2, 'a', 'c', 'b']; delete actual[5]; var expected = [null, 'f', 'e', 'd', 'c', 'b', 'a', undefined]; expected.length = 9; actual.sort(descending); expect(actual).toEqual(expected); }); it('[] should result in []', function () { var actual = []; var expected = []; actual.sort(descending); expect(actual).toEqual(expected); }); it('[1] should result in [1]', function () { var actual = [1]; var expected = [1]; actual.sort(descending); expect(actual).toEqual(expected); }); it('result should find only lesser or equal values', function () { var actual = []; var i; for (i = 0; i < 100; i += 1) { actual.push(('00' + (Math.random() * 100).toFixed(0)).slice(-3)); } actual.sort(descending); for (i = 0; i < actual.length - 1; i += 1) { expect(actual[i] >= actual[i + 1]).toBe(true); } }); }); describe('returned value', function () { it('should be the source object', function () { var actual = [1, 3, 2]; expect(actual.sort()).toBe(actual); }); }); describe('when used generically', function () { var descending = function (left, right) { var leftS = String(left); var rightS = String(right); if (leftS === rightS) { return +0; } if (leftS < rightS) { return 1; } return -1; }; var args = function () { return arguments; }; it('should not sort objects without length', function () { var actual = { 0: 5, 1: 2, 2: 4, 3: 6, 4: 1, 5: 3 }; var expected = { 0: 5, 1: 2, 2: 4, 3: 6, 4: 1, 5: 3 }; Array.prototype.sort.call(actual); expect(actual).toEqual(expected); Array.prototype.sort.call(actual, descending); expect(actual).toEqual(expected); }); it('should sort objects ascending with length', function () { var actual = { 0: 5, 1: 2, 2: 4, 3: 6, 4: 1, 5: 3, length: 6 }; var expected = { 0: 1, 1: 2, 2: 3, 3: 4, 4: 5, 5: 6, length: 6 }; Array.prototype.sort.call(actual); expect(actual).toEqual(expected); }); it('should sort objects descending with length', function () { var actual = { 0: 5, 1: 2, 2: 4, 3: 6, 4: 1, 5: 3, length: 6 }; var expected = { 0: 6, 1: 5, 2: 4, 3: 3, 4: 2, 5: 1, length: 6 }; Array.prototype.sort.call(actual, descending); expect(actual).toEqual(expected); }); it('should sort objects descending with mixed content types and with length', function () { var actual = { 0: 5, 1: 2, 2: 4, 4: null, 6: 1, 7: 3, length: 8 }; var expected = { 0: null, 1: 5, 2: 4, 3: 3, 4: 2, 5: 1, length: 8 }; Array.prototype.sort.call(actual, descending); expect(actual).toEqual(expected); }); it('should sort `arguments` object ascending', function () { var actual = args(5, 2, 4, 6, 1, 3); var expected = args(1, 2, 3, 4, 5, 6); Array.prototype.sort.call(actual); expect(actual).toEqual(expected); }); it('should sort `arguments` object ascending with mixed content types', function () { var actual = args(5, 2, 4, null, 1, 3); var expected = args(1, 2, 3, 4, 5, null); Array.prototype.sort.call(actual); expect(actual).toEqual(expected); }); it('should sort `arguments` object descending', function () { var actual = args(5, 2, 4, 6, 1, 3); var expected = args(6, 5, 4, 3, 2, 1); Array.prototype.sort.call(actual, descending); expect(actual).toEqual(expected); }); it('should sort `arguments` object descending with mixed content types', function () { var actual = args(5, 2, 4, null, 1, 3); var expected = args(null, 5, 4, 3, 2, 1); Array.prototype.sort.call(actual, descending); expect(actual).toEqual(expected); }); }); }); }); es5-shim-4.4.1/tests/spec/s-date.js000066400000000000000000000402531263422513500167700ustar00rootroot00000000000000/* global describe, it, xit, expect, beforeEach, jasmine */ describe('Date', function () { 'use strict'; var supportsDescriptors = Object.defineProperty && (function () { try { var obj = {}; Object.defineProperty(obj, 'x', { enumerable: false, value: obj }); for (var _ in obj) { return false; } return obj.x === obj; } catch (e) { /* this is ES3 */ return false; } }()); var ifSupportsDescriptorsIt = supportsDescriptors ? it : xit; var has = Object.prototype.hasOwnProperty; describe('.now()', function () { it('should be the current time', function () { var before = (new Date()).getTime(); var middle = Date.now(); var after = (new Date()).getTime(); expect(middle).not.toBeLessThan(before); expect(middle).not.toBeGreaterThan(after); }); }); describe('constructor', function () { it('works with standard formats', function () { // Chrome 19 Opera 12 Firefox 11 IE 9 Safari 5.1.1 expect(+new Date('2012-12-31T23:59:59.000Z')).toBe(1356998399000); // 1356998399000 1356998399000 1356998399000 1356998399000 1356998399000 expect(+new Date('2012-04-04T05:02:02.170Z')).toBe(1333515722170); // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 expect(+new Date('2012-04-04T05:02:02.170999Z')).toBe(1333515722170); // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 expect(+new Date('2012-04-04T05:02:02.17Z')).toBe(1333515722170); // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 expect(+new Date('2012-04-04T05:02:02.1Z')).toBe(1333515722100); // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 expect(+new Date('2012-04-04T24:00:00.000Z')).toBe(1333584000000); // NaN 1333584000000 1333584000000 1333584000000 1333584000000 expect(+new Date('2012-02-29T12:00:00.000Z')).toBe(1330516800000); // 1330516800000 1330516800000 1330516800000 1330516800000 1330516800000 expect(+new Date('2011-03-01T12:00:00.000Z')).toBe(1298980800000); // 1298980800000 1298980800000 1298980800000 1298980800000 1298980800000 // https://github.com/es-shims/es5-shim/issues/80 Safari bug with leap day expect(new Date('2034-03-01T00:00:00.000Z') - new Date('2034-02-27T23:59:59.999Z')).toBe(86400001); // 86400001 86400001 86400001 86400001 1 }); ifSupportsDescriptorsIt('is not enumerable', function () { expect(Object.keys(new Date())).not.toContain('constructor'); }); it('works as a function', function () { var zeroDate = Date(0); expect(zeroDate).toBe(String(zeroDate)); var value = Date(1441705534578); expect(value).toBe(String(value)); }); it('fixes this Safari 8/9 bug', function () { var offset = new Date(1970).getTimezoneOffset() * 60e3; var timestamp = 2147483647; // Math.pow(2, 31) - 1 var date = new Date(1970, 0, 1, 0, 0, 0, timestamp); var expectedTimestamp = timestamp + offset; expect(date.getTime()).toBe(expectedTimestamp); var brokenTimestamp = 2147483648; // Math.pow(2, 31) var brokenDate = new Date(1970, 0, 1, 0, 0, 0, brokenTimestamp); var expectedBrokenTimestamp = brokenTimestamp + offset; expect(brokenDate.getTime()).toBe(expectedBrokenTimestamp); // NaN in Safari 8/9 var veryBrokenTS = 1435734000000; var veryBrokenDate = new Date(1970, 0, 1, 0, 0, 0, veryBrokenTS); var largeDate = new Date('Wed Jul 01 2015 07:00:00 GMT-0700 (PDT)'); var expectedVeryBrokenTS = veryBrokenTS + (largeDate.getTimezoneOffset() * 60e3); expect(veryBrokenDate.getTime()).toBe(expectedVeryBrokenTS); // NaN in Safari 8/9 }); }); describe('.parse()', function () { // TODO: Write the rest of the test. ifSupportsDescriptorsIt('is not enumerable', function () { expect(Object.getOwnPropertyDescriptor(Date, 'parse').enumerable).toBe(false); }); it('should be an invalid date', function () { // Chrome 19 Opera 12 Firefox 11 IE 9 Safari 5.1.1 expect(Date.parse('2012-11-31T23:59:59.000Z')).toBeFalsy(); // 1354406399000 NaN NaN 1354406399000 NaN expect(Date.parse('2012-12-31T23:59:60.000Z')).toBeFalsy(); // NaN NaN NaN NaN 1356998400000 expect(Date.parse('2012-04-04T24:00:00.500Z')).toBeFalsy(); // NaN NaN 1333584000500 1333584000500 NaN expect(Date.parse('2012-12-31T10:08:60.000Z')).toBeFalsy(); // NaN NaN NaN NaN 1356948540000 expect(Date.parse('2012-13-01T12:00:00.000Z')).toBeFalsy(); // NaN NaN NaN NaN NaN expect(Date.parse('2012-12-32T12:00:00.000Z')).toBeFalsy(); // NaN NaN NaN NaN NaN expect(Date.parse('2012-12-31T25:00:00.000Z')).toBeFalsy(); // NaN NaN NaN NaN NaN expect(Date.parse('2012-12-31T24:01:00.000Z')).toBeFalsy(); // NaN NaN NaN 1356998460000 NaN expect(Date.parse('2012-12-31T12:60:00.000Z')).toBeFalsy(); // NaN NaN NaN NaN NaN expect(Date.parse('2012-12-31T12:00:60.000Z')).toBeFalsy(); // NaN NaN NaN NaN 1356955260000 expect(Date.parse('2012-00-31T23:59:59.000Z')).toBeFalsy(); // NaN NaN NaN NaN NaN expect(Date.parse('2012-12-00T23:59:59.000Z')).toBeFalsy(); // NaN NaN NaN NaN NaN expect(Date.parse('2011-02-29T12:00:00.000Z')).toBeFalsy(); // 1298980800000 NaN NaN 1298980800000 NaN }); it('should work', function () { var dates = { // Chrome 19 Opera 12 Firefox 11 IE 9 Safari 5.1.1 Safari 8 '2012-12-31T23:59:59.000Z': 1356998399000, // 1356998399000 1356998399000 1356998399000 1356998399000 1356998399000 1356998399000 '2012-04-04T05:02:02.170Z': 1333515722170, // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 '2012-04-04T05:02:02.170999Z': 1333515722170, // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170.999 '2012-04-04T05:02:02.17Z': 1333515722170, // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 '2012-04-04T05:02:02.1Z': 1333515722100, // 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 1333515722170 '2012-04-04T24:00:00.000Z': 1333584000000, // NaN 1333584000000 1333584000000 1333584000000 1333584000000 1333584000000 '2012-02-29T12:00:00.000Z': 1330516800000, // 1330516800000 1330516800000 1330516800000 1330516800000 1330516800000 1330516800000 '2011-03-01T12:00:00.000Z': 1298980800000 // 1298980800000 1298980800000 1298980800000 1298980800000 1298980800000 1298980800000 }; for (var str in dates) { if (has.call(dates, str)) { expect(Math.floor(Date.parse(str))).toBe(dates[str]); } } // https://github.com/es-shims/es5-shim/issues/80 Safari bug with leap day expect(Date.parse('2034-03-01T00:00:00.000Z') - Date.parse('2034-02-27T23:59:59.999Z')).toBe(86400001); // 86400001 86400001 86400001 86400001 1 }); it('fixes a Safari 8/9 bug with parsing in UTC instead of local time', function () { var offset = new Date('2015-07-01').getTimezoneOffset() * 60e3; expect(Date.parse('2015-07-01T00:00:00')).toBe(1435708800000 + offset); // Safari 8/9 give NaN }); it('should support extended years', function () { // Chrome 19 Opera 12 Firefox 11 IE 9 Safari 5.1.1 expect(Date.parse('0000-01-01T00:00:00.000Z')).toBe(-621672192e5); // -621672192e5 -621672192e5 -621672192e5 -621672192e5 -621672192e5 expect(Date.parse('0001-01-01T00:00:00Z')).toBe(-621355968e5); // -621355968e5 -621355968e5 -621355968e5 8.64e15 -621355968e5 expect(Date.parse('+275760-09-13T00:00:00.000Z')).toBe(8.64e15); // 8.64e15 NaN 8.64e15 8.64e15 8.64e15 expect(Date.parse('-271821-04-20T00:00:00.000Z')).toBe(-8.64e15); // -8.64e15 NaN -8.64e15 -8.64e15 -8.6400000864e15 expect(Date.parse('+275760-09-13T00:00:00.001Z')).toBeFalsy(); // NaN NaN NaN 8.64e15 + 1 8.64e15 + 1 expect(Date.parse('-271821-04-19T23:59:59.999Z')).toBeFalsy(); // NaN NaN NaN -8.64e15 - 1 -8.6400000864e15 - 1 expect(Date.parse('+033658-09-27T01:46:40.000Z')).toBe(1e15); // 1e15 NaN 1e15 1e15 9999999136e5 expect(Date.parse('-000001-01-01T00:00:00Z')).toBe(-621987552e5); // -621987552e5 NaN -621987552e5 -621987552e5 -621987552e5 expect(Date.parse('+002009-12-15T00:00:00Z')).toBe(12608352e5); // 12608352e5 NaN 12608352e5 12608352e5 12608352e5 }); it('works with timezone offsets', function () { // Chrome 19 Opera 12 Firefox 11 IE 9 Safari 5.1.1 expect(Date.parse('2012-01-29T12:00:00.000+01:00')).toBe(132783480e4); // 132783480e4 132783480e4 132783480e4 132783480e4 132783480e4 expect(Date.parse('2012-01-29T12:00:00.000-00:00')).toBe(132783840e4); // 132783840e4 132783840e4 132783840e4 132783840e4 132783840e4 expect(Date.parse('2012-01-29T12:00:00.000+00:00')).toBe(132783840e4); // 132783840e4 132783840e4 132783840e4 132783840e4 132783840e4 expect(Date.parse('2012-01-29T12:00:00.000+23:59')).toBe(132775206e4); // 132775206e4 132775206e4 132775206e4 132775206e4 132775206e4 expect(Date.parse('2012-01-29T12:00:00.000-23:59')).toBe(132792474e4); // 132792474e4 132792474e4 132792474e4 132792474e4 132792474e4 expect(Date.parse('2012-01-29T12:00:00.000+24:00')).toBeFalsy(); // NaN 1327752e6 NaN 1327752000000 1327752000000 expect(Date.parse('2012-01-29T12:00:00.000+24:01')).toBeFalsy(); // NaN NaN NaN 1327751940000 1327751940000 expect(Date.parse('2012-01-29T12:00:00.000+24:59')).toBeFalsy(); // NaN NaN NaN 1327748460000 1327748460000 expect(Date.parse('2012-01-29T12:00:00.000+25:00')).toBeFalsy(); // NaN NaN NaN NaN NaN expect(Date.parse('2012-01-29T12:00:00.000+00:60')).toBeFalsy(); // NaN NaN NaN NaN NaN expect(Date.parse('-271821-04-20T00:00:00.000+00:01')).toBeFalsy(); // NaN NaN NaN -864000000006e4 -864000008646e4 expect(Date.parse('-271821-04-20T00:01:00.000+00:01')).toBe(-8.64e15); // -8.64e15 NaN -8.64e15 -8.64e15 -864000008640e4 // When time zone is missed, local offset should be used (ES 5.1 bug) // see https://bugs.ecmascript.org/show_bug.cgi?id=112 var tzOffset = Number(new Date(1970, 0)); // same as (new Date().getTimezoneOffset() * 60000) expect(Date.parse('1970-01-01T00:00:00')).toBe(tzOffset); // tzOffset 0 0 0 NaN }); it('should be able to coerce to a number', function () { var actual = Number(new Date(1970, 0)); var expected = parseInt(actual, 10); expect(actual).toBeDefined(); expect(actual).toBe(expected); expect(isNaN(actual)).toBeFalsy(); }); }); describe('#toString()', function () { var actual; beforeEach(function () { actual = (new Date(1970, 0)).toString(); }); it('should show correct date info for ' + actual, function () { expect(actual).toMatch(/1970/); expect(actual).toMatch(/jan/i); expect(actual).toMatch(/thu/i); expect(actual).toMatch(/00:00:00/); }); }); describe('#valueOf()', function () { // Note that new Date(1970, 0).valueOf() is 0 in UTC timezone. // Check check that it's a number (and an int), not that it's "truthy". var actual; beforeEach(function () { actual = (new Date(1970, 0)).valueOf(); }); it('should give a numeric value', function () { expect(typeof actual).toBe('number'); }); it('should not be NaN', function () { expect(isNaN(actual)).toBe(false); }); it('should give an int value', function () { expect(actual).toBe(Math.floor(actual)); }); }); describe('#getUTCDate()', function () { it('should return the right value for negative dates', function () { // Opera 10.6/11.61/Opera 12 bug expect(new Date(-3509827334573292).getUTCDate()).toBe(1); }); }); describe('#getUTCMonth()', function () { it('should return the right value for negative dates', function () { // Opera 10.6/11.61/Opera 12 bug expect(new Date(-3509827334573292).getUTCMonth()).toBe(0); }); it('should return correct values', function () { expect(new Date(8.64e15).getUTCMonth()).toBe(8); expect(new Date(0).getUTCMonth()).toBe(0); }); }); describe('#toISOString()', function () { // TODO: write the rest of the test. it('should support extended years', function () { expect(new Date(-62198755200000).toISOString().indexOf('-000001-01-01')).toBe(0); expect(new Date(8.64e15).toISOString().indexOf('+275760-09-13')).toBe(0); }); it('should return correct dates', function () { expect(new Date(-1).toISOString()).toBe('1969-12-31T23:59:59.999Z');// Safari 5.1.5 "1969-12-31T23:59:59.-01Z" expect(new Date(-3509827334573292).toISOString()).toBe('-109252-01-01T10:37:06.708Z'); // Opera 11.61/Opera 12 bug with Date#getUTCMonth }); }); describe('#toJSON()', function () { // Opera 11.6x/12 bug it('should call toISOString', function () { var date = new Date(0); date.toISOString = function () { return 1; }; expect(date.toJSON()).toBe(1); }); it('should return null for not finite dates', function () { var date = new Date(NaN), json; try { json = date.toJSON(); } catch (e) { /* invalid json */ expect(e).not.toEqual(jasmine.any(Error)); } expect(json).toBe(null); }); it('should return the isoString when stringified', function () { var date = new Date(); expect(JSON.stringify(date.toISOString())).toBe(JSON.stringify(date)); }); }); }); es5-shim-4.4.1/tests/spec/s-error.js000066400000000000000000000032711263422513500172030ustar00rootroot00000000000000/* global describe, it, xit, expect */ describe('Error', function () { 'use strict'; var supportsDescriptors = Object.defineProperty && (function () { try { var obj = {}; Object.defineProperty(obj, 'x', { enumerable: false, value: obj }); for (var _ in obj) { return false; } return obj.x === obj; } catch (e) { /* this is ES3 */ return false; } }()); var ifSupportsDescriptorsIt = supportsDescriptors ? it : xit; describe('#toString()', function () { it('stringifies a newed error properly', function () { var msg = 'test'; var error = new RangeError(msg); expect(error.name).toBe('RangeError'); expect(error.message).toBe(msg); expect(String(error)).toBe(error.name + ': ' + msg); }); it('stringifies a thrown error properly', function () { var msg = 'test'; var error; try { throw new RangeError(msg); } catch (e) { error = e; } expect(error.name).toBe('RangeError'); expect(error.message).toBe(msg); expect(String(error)).toBe(error.name + ': ' + msg); }); }); describe('enumerability of prototype properties', function () { ifSupportsDescriptorsIt('#message', function () { expect(Object.prototype.propertyIsEnumerable.call(Error.prototype, 'message')).toBe(false); }); ifSupportsDescriptorsIt('#name', function () { expect(Object.prototype.propertyIsEnumerable.call(Error.prototype, 'name')).toBe(false); }); }); }); es5-shim-4.4.1/tests/spec/s-function.js000066400000000000000000000157521263422513500177060ustar00rootroot00000000000000/* global describe, it, expect, beforeEach */ describe('Function', function () { 'use strict'; describe('#apply()', function () { it('works with arraylike objects', function () { var arrayLike = { length: 4, 0: 1, 2: 4, 3: true }; var expectedArray = [1, undefined, 4, true]; var actualArray = (function () { return Array.prototype.slice.apply(arguments); }.apply(null, arrayLike)); expect(actualArray).toEqual(expectedArray); }); }); describe('#bind()', function () { var actual; var testSubject = { push: function (o) { this.a.push(o); } }; var func = function func() { Array.prototype.forEach.call(arguments, function (a) { this.push(a); }, this); return this; }; beforeEach(function () { actual = []; testSubject.a = []; }); it('binds properly without a context', function () { var context; testSubject.func = function () { context = this; }.bind(); testSubject.func(); expect(context).toBe(function () { return this; }.call()); }); it('binds properly without a context, and still supplies bound arguments', function () { var a, context; testSubject.func = function () { a = Array.prototype.slice.call(arguments); context = this; }.bind(undefined, 1, 2, 3); testSubject.func(1, 2, 3); expect(a).toEqual([1, 2, 3, 1, 2, 3]); expect(context).toBe(function () { return this; }.call()); }); it('binds a context properly', function () { testSubject.func = func.bind(actual); testSubject.func(1, 2, 3); expect(actual).toEqual([1, 2, 3]); expect(testSubject.a).toEqual([]); }); it('binds a context and supplies bound arguments', function () { testSubject.func = func.bind(actual, 1, 2, 3); testSubject.func(4, 5, 6); expect(actual).toEqual([1, 2, 3, 4, 5, 6]); expect(testSubject.a).toEqual([]); }); it('returns properly without binding a context', function () { testSubject.func = function () { return this; }.bind(); var context = testSubject.func(); expect(context).toBe(function () { return this; }.call()); }); it('returns properly without binding a context, and still supplies bound arguments', function () { var context; testSubject.func = function () { context = this; return Array.prototype.slice.call(arguments); }.bind(undefined, 1, 2, 3); actual = testSubject.func(1, 2, 3); expect(context).toBe(function () { return this; }.call()); expect(actual).toEqual([1, 2, 3, 1, 2, 3]); }); it('returns properly while binding a context properly', function () { var ret; testSubject.func = func.bind(actual); ret = testSubject.func(1, 2, 3); expect(ret).toBe(actual); expect(ret).not.toBe(testSubject); }); it('returns properly while binding a context and supplies bound arguments', function () { var ret; testSubject.func = func.bind(actual, 1, 2, 3); ret = testSubject.func(4, 5, 6); expect(ret).toBe(actual); expect(ret).not.toBe(testSubject); }); it('has the new instance\'s context as a constructor', function () { var actualContext; var expectedContext = { foo: 'bar' }; testSubject.Func = function () { actualContext = this; }.bind(expectedContext); var result = new testSubject.Func(); expect(result).toBeTruthy(); expect(actualContext).not.toBe(expectedContext); }); it('passes the correct arguments as a constructor', function () { var expected = { name: 'Correct' }; testSubject.Func = function (arg) { expect(this.hasOwnProperty('name')).toBe(false); return arg; }.bind({ name: 'Incorrect' }); var ret = new testSubject.Func(expected); expect(ret).toBe(expected); }); it('returns the return value of the bound function when called as a constructor', function () { var oracle = [1, 2, 3]; var Subject = function () { expect(this).not.toBe(oracle); return oracle; }.bind(null); var result = new Subject(); expect(result).toBe(oracle); }); it('returns the correct value if constructor returns primitive', function () { var Subject = function (oracle) { expect(this).not.toBe(oracle); return oracle; }.bind(null); var primitives = ['asdf', null, true, 1]; for (var i = 0; i < primitives.length; ++i) { expect(new Subject(primitives[i])).not.toBe(primitives[i]); } var objects = [[1, 2, 3], {}, function () {}]; for (var j = 0; j < objects.length; ++j) { expect(new Subject(objects[j])).toBe(objects[j]); } }); it('returns the value that instance of original "class" when called as a constructor', function () { var ClassA = function (x) { this.name = x || 'A'; }; var ClassB = ClassA.bind(null, 'B'); var result = new ClassB(); expect(result instanceof ClassA).toBe(true); expect(result instanceof ClassB).toBe(true); }); it('sets a correct length without thisArg', function () { var Subject = function (a, b, c) { return a + b + c; }.bind(); expect(Subject.length).toBe(3); }); it('sets a correct length with thisArg', function () { var Subject = function (a, b, c) { return a + b + c + this.d; }.bind({ d: 1 }); expect(Subject.length).toBe(3); }); it('sets a correct length with thisArg and first argument', function () { var Subject = function (a, b, c) { return a + b + c + this.d; }.bind({ d: 1 }, 1); expect(Subject.length).toBe(2); }); it('sets a correct length without thisArg and first argument', function () { var Subject = function (a, b, c) { return a + b + c; }.bind(undefined, 1); expect(Subject.length).toBe(2); }); it('sets a correct length without thisArg and too many argument', function () { var Subject = function (a, b, c) { return a + b + c; }.bind(undefined, 1, 2, 3, 4); expect(Subject.length).toBe(0); }); }); }); es5-shim-4.4.1/tests/spec/s-global.js000066400000000000000000000045411263422513500173130ustar00rootroot00000000000000/* global describe, it, xit, expect */ describe('global methods', function () { 'use strict'; var foo = function foo() {}; var functionsHaveNames = foo.name === 'foo'; var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit; describe('parseInt', function () { /* eslint-disable radix */ ifFunctionsHaveNamesIt('has the right name', function () { expect(parseInt.name).toBe('parseInt'); }); it('accepts a radix', function () { for (var i = 2; i <= 36; ++i) { expect(parseInt('10', i)).toBe(i); } }); it('defaults the radix to 10 when the number does not start with 0x or 0X', function () { [ '01', '08', '10', '42' ].forEach(function (str) { expect(parseInt(str)).toBe(parseInt(str, 10)); }); }); it('defaults the radix to 16 when the number starts with 0x or 0X', function () { expect(parseInt('0x16')).toBe(parseInt('0x16', 16)); expect(parseInt('0X16')).toBe(parseInt('0X16', 16)); }); it('ignores leading whitespace', function () { expect(parseInt(' 0x16')).toBe(parseInt('0x16', 16)); expect(parseInt(' 42')).toBe(parseInt('42', 10)); expect(parseInt(' 08')).toBe(parseInt('08', 10)); var ws = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003' + '\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028' + '\u2029\uFEFF'; expect(parseInt(ws + '08')).toBe(parseInt('08', 10)); expect(parseInt(ws + '0x16')).toBe(parseInt('0x16', 16)); }); it('defaults the radix properly when not a true number', function () { var fakeZero = { valueOf: function () { return 0; } }; expect(parseInt('08', fakeZero)).toBe(parseInt('08', 10)); expect(parseInt('0x16', fakeZero)).toBe(parseInt('0x16', 16)); }); it('allows sign-prefixed hex values', function () { expect(parseInt('-0xF')).toBe(-15); expect(parseInt('-0xF', 16)).toBe(-15); expect(parseInt('+0xF')).toBe(15); expect(parseInt('+0xF', 16)).toBe(15); }); /* eslint-enable radix */ }); }); es5-shim-4.4.1/tests/spec/s-number.js000066400000000000000000000040551263422513500173430ustar00rootroot00000000000000/* global describe, it, expect */ describe('Number', function () { 'use strict'; describe('#toFixed()', function () { it('should convert numbers correctly', function () { expect((0.00008).toFixed(3)).toBe('0.000'); expect((0.9).toFixed(0)).toBe('1'); expect((1.255).toFixed(2)).toBe('1.25'); expect((1843654265.0774949).toFixed(5)).toBe('1843654265.07749'); expect((1000000000000000128).toFixed(0)).toBe('1000000000000000128'); }); }); describe('#toPrecision()', function () { // the spec allows for this test to fail. it('throws a RangeError when < 1 or > 21', function () { expect(function () { return (0.9).toPrecision(0); }).toThrow(); // Firefox allows values up to 100 expect(function () { return (0.9).toPrecision(101); }).toThrow(); }); it('works as expected', function () { expect((0.00008).toPrecision(3)).toBe('0.0000800'); expect((1.255).toPrecision(2)).toBe('1.3'); expect((1843654265.0774949).toPrecision(13)).toBe('1843654265.077'); expect(NaN.toPrecision(1)).toBe('NaN'); }); it('works with an undefined precision', function () { var num = 123.456; expect(num.toPrecision()).toBe(String(num)); expect(num.toPrecision(undefined)).toBe(String(num)); }); }); describe('constants', function () { it('should have MAX_VALUE', function () { expect(Number.MAX_VALUE).toBe(1.7976931348623157e308); }); it('should have MIN_VALUE', function () { expect(Number.MIN_VALUE).toBe(5e-324); }); it('should have NaN', function () { expect(Number.NaN).not.toBe(Number.NaN); }); it('should have POSITIVE_INFINITY', function () { expect(Number.POSITIVE_INFINITY).toBe(Infinity); }); it('should have NEGATIVE_INFINITY', function () { expect(Number.NEGATIVE_INFINITY).toBe(-Infinity); }); }); }); es5-shim-4.4.1/tests/spec/s-object.js000066400000000000000000000303671263422513500173260ustar00rootroot00000000000000/* global describe, it, xit, expect, beforeEach, jasmine, window */ var supportsDescriptors = Object.defineProperty && (function () { try { var obj = {}; Object.defineProperty(obj, 'x', { enumerable: false, value: obj }); for (var _ in obj) { return false; } return obj.x === obj; } catch (e) { /* this is ES3 */ return false; } }()); var ifWindowIt = typeof window === 'undefined' ? xit : it; var extensionsPreventible = typeof Object.preventExtensions === 'function' && (function () { var obj = {}; Object.preventExtensions(obj); obj.a = 3; return obj.a !== 3; }()); var ifExtensionsPreventibleIt = extensionsPreventible ? it : xit; var canSeal = typeof Object.seal === 'function' && (function () { var obj = { a: 3 }; Object.seal(obj); delete obj.a; return obj.a === 3; }()); var ifCanSealIt = canSeal ? it : xit; var canFreeze = typeof Object.freeze === 'function' && (function () { var obj = {}; Object.freeze(obj); obj.a = 3; return obj.a !== 3; }()); var ifCanFreezeIt = canFreeze ? it : xit; describe('Object', function () { 'use strict'; describe('.keys()', function () { var obj = { str: 'boz', obj: { }, arr: [], bool: true, num: 42, 'null': null, undefined: undefined }; var loopedValues = []; for (var key in obj) { loopedValues.push(key); } var keys = Object.keys(obj); it('should have correct length', function () { expect(keys.length).toBe(7); }); describe('arguments objects', function () { it('works with an arguments object', function () { (function () { expect(arguments.length).toBe(3); expect(Object.keys(arguments).length).toBe(arguments.length); expect(Object.keys(arguments)).toEqual(['0', '1', '2']); }(1, 2, 3)); }); it('works with a legacy arguments object', function () { var FakeArguments = function (args) { args.forEach(function (arg, i) { this[i] = arg; }.bind(this)); }; FakeArguments.prototype.length = 3; FakeArguments.prototype.callee = function () {}; var fakeOldArguments = new FakeArguments(['a', 'b', 'c']); expect(Object.keys(fakeOldArguments)).toEqual(['0', '1', '2']); }); }); it('should return an Array', function () { expect(Array.isArray(keys)).toBe(true); }); it('should return names which are own properties', function () { keys.forEach(function (name) { expect(obj.hasOwnProperty(name)).toBe(true); }); }); it('should return names which are enumerable', function () { keys.forEach(function (name) { expect(loopedValues.indexOf(name)).toNotBe(-1); }); }); // ES6 Object.keys does not require this throw xit('should throw error for non object', function () { var e = {}; expect(function () { try { Object.keys(42); } catch (err) { throw e; } }).toThrow(e); }); describe('enumerating over non-enumerable properties', function () { it('has no enumerable keys on a Function', function () { var Foo = function () {}; expect(Object.keys(Foo.prototype)).toEqual([]); }); it('has no enumerable keys on a boolean', function () { expect(Object.keys(Boolean.prototype)).toEqual([]); }); it('has no enumerable keys on an object', function () { expect(Object.keys(Object.prototype)).toEqual([]); }); }); it('works with boxed primitives', function () { expect(Object.keys(Object('hello'))).toEqual(['0', '1', '2', '3', '4']); }); it('works with boxed primitives with extra properties', function () { var x = Object('x'); x.y = 1; var actual = Object.keys(x); var expected = ['0', 'y']; actual.sort(); expected.sort(); expect(actual).toEqual(expected); }); ifWindowIt('can serialize all objects on the `window`', function () { var has = Object.prototype.hasOwnProperty; var windowItemKeys, exception; var blacklistedKeys = ['window', 'console', 'parent', 'self', 'frame', 'frames', 'frameElement', 'external']; if (supportsDescriptors) { Object.defineProperty(window, 'thrower', { configurable: true, get: function () { throw new RangeError('thrower!'); } }); } for (var k in window) { windowItemKeys = exception = void 0; if (blacklistedKeys.indexOf(k) === -1 && has.call(window, k) && window[k] !== null && typeof window[k] === 'object') { try { windowItemKeys = Object.keys(window[k]); } catch (e) { exception = e; } expect(Array.isArray(windowItemKeys)).toBe(true); expect(exception).toBeUndefined(); } } if (supportsDescriptors) { delete window.thrower; } }); }); describe('.isExtensible()', function () { var obj = { }; it('should return true if object is extensible', function () { expect(Object.isExtensible(obj)).toBe(true); }); ifExtensionsPreventibleIt('should return false if object is not extensible', function () { expect(Object.isExtensible(Object.preventExtensions(obj))).toBe(false); }); ifCanSealIt('should return false if object is sealed', function () { expect(Object.isExtensible(Object.seal(obj))).toBe(false); }); ifCanFreezeIt('should return false if object is frozen', function () { expect(Object.isExtensible(Object.freeze(obj))).toBe(false); }); it('should throw error for non object', function () { try { // note: in ES6, this is expected to return false. expect(Object.isExtensible(42)).toBe(false); } catch (err) { expect(err).toEqual(jasmine.any(TypeError)); } }); }); describe('.defineProperty()', function () { var obj; beforeEach(function () { obj = {}; Object.defineProperty(obj, 'name', { value: 'Testing', configurable: true, enumerable: true, writable: true }); }); it('should return the initial value', function () { expect(obj.hasOwnProperty('name')).toBeTruthy(); expect(obj.name).toBe('Testing'); }); it('should be setable', function () { obj.name = 'Other'; expect(obj.name).toBe('Other'); }); it('should return the parent initial value', function () { var child = Object.create(obj, {}); expect(child.name).toBe('Testing'); expect(child.hasOwnProperty('name')).toBeFalsy(); }); it('should not override the parent value', function () { var child = Object.create(obj, {}); Object.defineProperty(child, 'name', { value: 'Other' }); expect(obj.name).toBe('Testing'); expect(child.name).toBe('Other'); }); it('should throw error for non object', function () { expect(function () { Object.defineProperty(42, 'name', {}); }).toThrow(); }); it('should not throw error for empty descriptor', function () { expect(function () { Object.defineProperty({}, 'name', {}); }).not.toThrow(); }); }); describe('.getOwnPropertyDescriptor()', function () { it('should return undefined because the object does not own the property', function () { var descr = Object.getOwnPropertyDescriptor({}, 'name'); expect(descr).toBeUndefined(); }); it('should return a data descriptor', function () { var descr = Object.getOwnPropertyDescriptor({ name: 'Testing' }, 'name'); var expected = { value: 'Testing', enumerable: true, writable: true, configurable: true }; expect(descr).toEqual(expected); }); it('should return undefined because the object does not own the property', function () { var descr = Object.getOwnPropertyDescriptor(Object.create({ name: 'Testing' }, {}), 'name'); expect(descr).toBeUndefined(); }); it('should return a data descriptor', function () { var expected = { value: 'Testing', configurable: true, enumerable: true, writable: true }; var obj = Object.create({}, { name: expected }); var descr = Object.getOwnPropertyDescriptor(obj, 'name'); expect(descr).toEqual(expected); }); it('should throw error for non object', function () { try { // note: in ES6, we expect this to return undefined. expect(Object.getOwnPropertyDescriptor(42, 'name')).toBeUndefined(); } catch (err) { expect(err).toEqual(jasmine.any(TypeError)); } }); }); describe('.getPrototypeOf()', function () { it('should return the [[Prototype]] of an object', function () { var Foo = function () {}; var proto = Object.getPrototypeOf(new Foo()); expect(proto).toBe(Foo.prototype); }); it('should shamone to the `Object.prototype` if `object.constructor` is not a function', function () { var Foo = function () {}; Foo.prototype.constructor = 1; var proto = Object.getPrototypeOf(new Foo()), fnToString = Function.prototype.toString; if (fnToString.call(Object.getPrototypeOf).indexOf('[native code]') < 0) { expect(proto).toBe(Object.prototype); } else { expect(proto).toBe(Foo.prototype); } }); it('should throw error for non object', function () { try { expect(Object.getPrototypeOf(1)).toBe(Number.prototype); // ES6 behavior } catch (err) { expect(err).toEqual(jasmine.any(TypeError)); } }); it('should return null on Object.create(null)', function () { var obj = Object.create(null); expect(Object.getPrototypeOf(obj) === null).toBe(true); }); }); describe('.defineProperties()', function () { it('should define the constructor property', function () { var target = {}; var newProperties = { constructor: { value: 'new constructor' } }; Object.defineProperties(target, newProperties); expect(target.constructor).toBe('new constructor'); }); }); describe('.create()', function () { it('should create objects with no properties when called as `Object.create(null)`', function () { var obj = Object.create(null); expect('hasOwnProperty' in obj).toBe(false); expect('toString' in obj).toBe(false); expect('constructor' in obj).toBe(false); var protoIsEnumerable = false; for (var k in obj) { if (k === '__proto__') { protoIsEnumerable = true; } } expect(protoIsEnumerable).toBe(false); expect(obj instanceof Object).toBe(false); }); }); }); es5-shim-4.4.1/tests/spec/s-regexp.js000066400000000000000000000021571263422513500173460ustar00rootroot00000000000000/* global describe, it, expect */ describe('RegExp', function () { 'use strict'; describe('#toString()', function () { describe('literals', function () { it('should return correct flags and in correct order', function () { expect(String(/pattern/)).toBe('/pattern/'); expect(String(/pattern/i)).toBe('/pattern/i'); expect(String(/pattern/mi)).toBe('/pattern/im'); expect(String(/pattern/im)).toBe('/pattern/im'); expect(String(/pattern/mgi)).toBe('/pattern/gim'); }); }); describe('objects', function () { it('should return correct flags and in correct order', function () { expect(String(new RegExp('pattern'))).toBe('/pattern/'); expect(String(new RegExp('pattern', 'i'))).toBe('/pattern/i'); expect(String(new RegExp('pattern', 'mi'))).toBe('/pattern/im'); expect(String(new RegExp('pattern', 'im'))).toBe('/pattern/im'); expect(String(new RegExp('pattern', 'mgi'))).toBe('/pattern/gim'); }); }); }); }); es5-shim-4.4.1/tests/spec/s-string.js000066400000000000000000000316461263422513500173670ustar00rootroot00000000000000/* global describe, it, expect */ describe('String', function () { 'use strict'; describe('#trim()', function () { var test = '\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFFHello, World!\x09\x0A\x0B\x0C\x0D\x20\xA0\u1680\u180E\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200A\u202F\u205F\u3000\u2028\u2029\uFEFF'; it('trims all ES5 whitespace', function () { expect(test.trim()).toBe('Hello, World!'); expect(test.trim().length).toBe(13); }); it('does not trim the zero-width space', function () { expect('\u200b'.trim()).toBe('\u200b'); expect('\u200b'.trim().length).toBe(1); }); }); describe('#replace()', function () { it('returns undefined for non-capturing groups', function () { var groups = []; 'x'.replace(/x(.)?/g, function (m, group) { groups.push(group); /* "" in FF, `undefined` in CH/WK/IE */ }); expect(groups.length).toBe(1); expect(groups[0]).toBeUndefined(); }); it('should not fail in Firefox', function () { expect(function () { return '* alef\n* beth \n* gimel~0\n'.replace( /(\n)?(^[ \t]*)([*+-]|\d+[.])[ \t]+([^\r]+?(\n{1,2}))(?=\n*(~0|\2([*+-]|\d+[.])[ \t]+))/gm, function (match, m1, m2, m3, m4) { return '
  • ' + m4 + '
  • \n'; } ); }).not.toThrow(); }); }); describe('#split()', function () { var test = 'ab'; it('If "separator" is undefined must return Array with one String - "this" string', function () { expect(test.split()).toEqual([test]); expect(test.split(void 0)).toEqual([test]); }); it('If "separator" is undefined and "limit" set to 0 must return Array[]', function () { expect(test.split(void 0, 0)).toEqual([]); }); describe('Tests from Steven Levithan', function () { it("''.split() results in ['']", function () { expect(''.split()).toEqual(['']); }); it("''.split(/./) results in ['']", function () { expect(''.split(/./)).toEqual(['']); }); it("''.split(/.?/) results in []", function () { expect(''.split(/.?/)).toEqual([]); }); it("''.split(/.??/) results in []", function () { expect(''.split(/.??/)).toEqual([]); }); it("'ab'.split(/a*/) results in ['', 'b']", function () { expect('ab'.split(/a*/)).toEqual(['', 'b']); }); it("'ab'.split(/a*?/) results in ['a', 'b']", function () { expect('ab'.split(/a*?/)).toEqual(['a', 'b']); }); it("'ab'.split(/(?:ab)/) results in ['', '']", function () { expect('ab'.split(/(?:ab)/)).toEqual(['', '']); }); it("'ab'.split(/(?:ab)*/) results in ['', '']", function () { expect('ab'.split(/(?:ab)*/)).toEqual(['', '']); }); it("'ab'.split(/(?:ab)*?/) results in ['a', 'b']", function () { expect('ab'.split(/(?:ab)*?/)).toEqual(['a', 'b']); }); it("'test'.split('') results in ['t', 'e', 's', 't']", function () { expect('test'.split('')).toEqual(['t', 'e', 's', 't']); }); it("'test'.split() results in ['test']", function () { expect('test'.split()).toEqual(['test']); }); it("'111'.split(1) results in ['', '', '', '']", function () { expect('111'.split(1)).toEqual(['', '', '', '']); }); it("'test'.split(/(?:)/, 2) results in ['t', 'e']", function () { expect('test'.split(/(?:)/, 2)).toEqual(['t', 'e']); }); it("'test'.split(/(?:)/, -1) results in ['t', 'e', 's', 't']", function () { expect('test'.split(/(?:)/, -1)).toEqual(['t', 'e', 's', 't']); }); it("'test'.split(/(?:)/, undefined) results in ['t', 'e', 's', 't']", function () { expect('test'.split(/(?:)/, undefined)).toEqual(['t', 'e', 's', 't']); }); it("'test'.split(/(?:)/, null) results in []", function () { expect('test'.split(/(?:)/, null)).toEqual([]); }); it("'test'.split(/(?:)/, NaN) results in []", function () { expect('test'.split(/(?:)/, NaN)).toEqual([]); }); it("'test'.split(/(?:)/, true) results in ['t']", function () { expect('test'.split(/(?:)/, true)).toEqual(['t']); }); it("'test'.split(/(?:)/, '2') results in ['t', 'e']", function () { expect('test'.split(/(?:)/, '2')).toEqual(['t', 'e']); }); it("'test'.split(/(?:)/, 'two') results in []", function () { expect('test'.split(/(?:)/, 'two')).toEqual([]); }); it("'a'.split(/-/) results in ['a']", function () { expect('a'.split(/-/)).toEqual(['a']); }); it("'a'.split(/-?/) results in ['a']", function () { expect('a'.split(/-?/)).toEqual(['a']); }); it("'a'.split(/-??/) results in ['a']", function () { expect('a'.split(/-??/)).toEqual(['a']); }); it("'a'.split(/a/) results in ['', '']", function () { expect('a'.split(/a/)).toEqual(['', '']); }); it("'a'.split(/a?/) results in ['', '']", function () { expect('a'.split(/a?/)).toEqual(['', '']); }); it("'a'.split(/a??/) results in ['a']", function () { expect('a'.split(/a??/)).toEqual(['a']); }); it("'ab'.split(/-/) results in ['ab']", function () { expect('ab'.split(/-/)).toEqual(['ab']); }); it("'ab'.split(/-?/) results in ['a', 'b']", function () { expect('ab'.split(/-?/)).toEqual(['a', 'b']); }); it("'ab'.split(/-??/) results in ['a', 'b']", function () { expect('ab'.split(/-??/)).toEqual(['a', 'b']); }); it("'a-b'.split(/-/) results in ['a', 'b']", function () { expect('a-b'.split(/-/)).toEqual(['a', 'b']); }); it("'a-b'.split(/-?/) results in ['a', 'b']", function () { expect('a-b'.split(/-?/)).toEqual(['a', 'b']); }); it("'a-b'.split(/-??/) results in ['a', '-', 'b']", function () { expect('a-b'.split(/-??/)).toEqual(['a', '-', 'b']); }); it("'a--b'.split(/-/) results in ['a', '', 'b']", function () { expect('a--b'.split(/-/)).toEqual(['a', '', 'b']); }); it("'a--b'.split(/-?/) results in ['a', '', 'b']", function () { expect('a--b'.split(/-?/)).toEqual(['a', '', 'b']); }); it("'a--b'.split(/-??/) results in ['a', '-', '-', 'b']", function () { expect('a--b'.split(/-??/)).toEqual(['a', '-', '-', 'b']); }); it("''.split(/()()/) results in []", function () { expect(''.split(/()()/)).toEqual([]); }); it("'.'.split(/()()/) results in ['.']", function () { expect('.'.split(/()()/)).toEqual(['.']); }); it("'.'.split(/(.?)(.?)/) results in ['', '.', '', '']", function () { expect('.'.split(/(.?)(.?)/)).toEqual(['', '.', '', '']); }); it("'.'.split(/(.??)(.??)/) results in ['.']", function () { expect('.'.split(/(.??)(.??)/)).toEqual(['.']); }); it("'.'.split(/(.)?(.)?/) results in ['', '.', undefined, '']", function () { expect('.'.split(/(.)?(.)?/)).toEqual(['', '.', undefined, '']); }); it("'Aboldandcoded'.split(/<(\\/)?([^<>]+)>/) results in ['A', undefined, 'B', 'bold', '/', 'B', 'and', undefined, 'CODE', 'coded', '/', 'CODE', '']", function () { expect('Aboldandcoded'.split(/<(\/)?([^<>]+)>/)).toEqual(['A', undefined, 'B', 'bold', '/', 'B', 'and', undefined, 'CODE', 'coded', '/', 'CODE', '']); }); it("'tesst'.split(/(s)*/) results in ['t', undefined, 'e', 's', 't']", function () { expect('tesst'.split(/(s)*/)).toEqual(['t', undefined, 'e', 's', 't']); }); it("'tesst'.split(/(s)*?/) results in ['t', undefined, 'e', undefined, 's', undefined, 's', undefined, 't']", function () { expect('tesst'.split(/(s)*?/)).toEqual(['t', undefined, 'e', undefined, 's', undefined, 's', undefined, 't']); }); it("'tesst'.split(/(s*)/) results in ['t', '', 'e', 'ss', 't']", function () { expect('tesst'.split(/(s*)/)).toEqual(['t', '', 'e', 'ss', 't']); }); it("'tesst'.split(/(s*?)/) results in ['t', '', 'e', '', 's', '', 's', '', 't']", function () { expect('tesst'.split(/(s*?)/)).toEqual(['t', '', 'e', '', 's', '', 's', '', 't']); }); it("'tesst'.split(/(?:s)*/) results in ['t', 'e', 't']", function () { expect('tesst'.split(/(?:s)*/)).toEqual(['t', 'e', 't']); }); it("'tesst'.split(/(?=s+)/) results in ['te', 's', 'st']", function () { expect('tesst'.split(/(?=s+)/)).toEqual(['te', 's', 'st']); }); it("'test'.split('t') results in ['', 'es', '']", function () { expect('test'.split('t')).toEqual(['', 'es', '']); }); it("'test'.split('es') results in ['t', 't']", function () { expect('test'.split('es')).toEqual(['t', 't']); }); it("'test'.split(/t/) results in ['', 'es', '']", function () { expect('test'.split(/t/)).toEqual(['', 'es', '']); }); it("'test'.split(/es/) results in ['t', 't']", function () { expect('test'.split(/es/)).toEqual(['t', 't']); }); it("'test'.split(/(t)/) results in ['', 't', 'es', 't', '']", function () { expect('test'.split(/(t)/)).toEqual(['', 't', 'es', 't', '']); }); it("'test'.split(/(es)/) results in ['t', 'es', 't']", function () { expect('test'.split(/(es)/)).toEqual(['t', 'es', 't']); }); it("'test'.split(/(t)(e)(s)(t)/) results in ['', 't', 'e', 's', 't', '']", function () { expect('test'.split(/(t)(e)(s)(t)/)).toEqual(['', 't', 'e', 's', 't', '']); }); it("'.'.split(/(((.((.??)))))/) results in ['', '.', '.', '.', '', '', '']", function () { expect('.'.split(/(((.((.??)))))/)).toEqual(['', '.', '.', '.', '', '', '']); }); it("'.'.split(/(((((.??)))))/) results in ['.']", function () { expect('.'.split(/(((((.??)))))/)).toEqual(['.']); }); it("'a b c d'.split(/ /, -(Math.pow(2, 32) - 1)) results in ['a']", function () { expect('a b c d'.split(/ /, -(Math.pow(2, 32) - 1))).toEqual(['a']); }); it("'a b c d'.split(/ /, Math.pow(2, 32) + 1) results in ['a']", function () { expect('a b c d'.split(/ /, Math.pow(2, 32) + 1)).toEqual(['a']); }); it("'a b c d'.split(/ /, Infinity) results in []", function () { expect('a b c d'.split(/ /, Infinity)).toEqual([]); }); }); }); describe('#indexOf()', function () { it('has basic support', function () { expect('abcab'.indexOf('a')).toBe(0); expect('abcab'.indexOf('a', 1)).toBe(3); expect('abcab'.indexOf('a', 4)).toBe(-1); }); it('works with unicode', function () { expect('あいabcあいabc'.indexOf('あい')).toBe(0); expect('あいabcあいabc'.indexOf('あい', 0)).toBe(0); expect('あいabcあいabc'.indexOf('あい', 1)).toBe(5); expect('あいabcあいabc'.indexOf('あい', 6)).toBe(-1); }); }); describe('#lastIndexOf()', function () { it('has the right length', function () { expect(String.prototype.lastIndexOf.length).toBe(1); }); it('has basic support', function () { expect('abcd'.lastIndexOf('d')).toBe(3); expect('abcd'.lastIndexOf('d', 3)).toBe(3); expect('abcd'.lastIndexOf('d', 2)).toBe(-1); }); it('works with unicode', function () { expect('abcあい'.lastIndexOf('あい')).toBe(3); expect('abcあい'.lastIndexOf('あい', 3)).toBe(3); expect('abcあい'.lastIndexOf('あい', 2)).toBe(-1); }); }); });