diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-19 01:47:29 +0000 |
commit | 0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d (patch) | |
tree | a31f07c9bcca9d56ce61e9a1ffd30ef350d513aa /third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim | |
parent | Initial commit. (diff) | |
download | firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.tar.xz firefox-esr-0ebf5bdf043a27fd3dfb7f92e0cb63d88954c44d.zip |
Adding upstream version 115.8.0esr.upstream/115.8.0esr
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim')
25 files changed, 6319 insertions, 0 deletions
diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/.gitignore b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/.gitignore new file mode 100644 index 0000000000..fd4f2b066b --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/.gitignore @@ -0,0 +1,2 @@ +node_modules +.DS_Store diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/CHANGES b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/CHANGES new file mode 100644 index 0000000000..f6f4f046e5 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/CHANGES @@ -0,0 +1,93 @@ + +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 <script> boilerplate + +1.2.2 + - Changed reduce to follow the letter of the spec with regard to having and + owning properties. + - Fixed a bug where RegExps pass as Functions in some engines in reduce. + +1.2.1 + - Adding few fixes to make jshint happy. + - Fix for issue #12, function expressions can cause scoping issues in IE. + - NPM will minify on install or when `npm run-script install` is executed. + - Adding .gitignore to avoid publishing dev dependencies. + +1.2.0 + - Making script loadable as AMD module. + - Adding `indexOf` to the list of safe shims. + +1.1.0 + - Added support for accessor properties where possible (which is all browsers + except IE). + - Stop exposing bound function's (that are returned by + `Function.prototype.bind`) internal properties (`bound, boundTo, boundArgs`) + as in some cases (when using facade objects for example) capabilities of the + enclosed functions will be leaked. + - `Object.create` now explicitly sets `__proto__` property to guarantee + correct behavior of `Object.getPrototypeOf`'s on all objects created using + `Object.create`. + - Switched to `===` from `==` where possible as it's slightly faster on older + browsers that are target of this lib. + - Added names to all anonymous functions to have a better stack traces. + +1.0.0 + - fixed Date.toISODate, using UTC accessors, as in + http://code.google.com/p/v8/source/browse/trunk/src/date.js?r=6120#986 + (arian) + +0.0.4 + - Revised Object.getPrototypeOf to work in more cases + in response to http://ejohn.org/blog/objectgetprototypeof/ + [issue #2] (fschaefer) + +0.0.3 + - Fixed typos in Object.keys (samsonjs) + +0.0.2 + Per kangax's recommendations: + - faster Object.create(null) + - fixed a function-scope function declaration statement in Object.create + +0.0.1 + - fixed Object.create(null), in so far as that's possible + - reworked Rhino Object.freeze(Function) bug detector and patcher + +0.0.0 + - forked from narwhal-lib + diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/CONTRIBUTORS.md b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/CONTRIBUTORS.md new file mode 100644 index 0000000000..56959a696a --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/CONTRIBUTORS.md @@ -0,0 +1,25 @@ + +- kriskowal Kris Kowal Copyright (C) 2009-2011 MIT License +- tlrobinson Tom Robinson Copyright (C) 2009-2010 MIT License (Narwhal + Project) +- dantman Daniel Friesen Copyright (C) 2010 XXX TODO License or CLA +- fschaefer Florian Schäfer Copyright (C) 2010 MIT License +- Gozala Irakli Gozalishvili Copyright (C) 2010 MIT License +- kitcambridge Kit Cambridge Copyright (C) 2011 MIT License +- kossnocorp Sasha Koss XXX TODO License or CLA +- bryanforbes Bryan Forbes XXX TODO License or CLA +- killdream Quildreen Motta Copyright (C) 2011 MIT Licence +- michaelficarra Michael Ficarra Copyright (C) 2011 3-clause BSD + License +- sharkbrainguy Gerard Paapu Copyright (C) 2011 MIT License +- bbqsrc Brendan Molloy (C) 2011 Creative Commons Zero (public domain) +- iwyg XXX TODO License or CLA +- DomenicDenicola Domenic Denicola Copyright (C) 2011 MIT License +- xavierm02 Montillet Xavier Copyright (C) 2011 MIT License +- Raynos Jake Verbaten Copyright (C) 2011 MIT Licence +- samsonjs Sami Samhuri Copyright (C) 2010 MIT License +- rwldrn Rick Waldron Copyright (C) 2011 MIT License +- lexer Alexey Zakharov XXX TODO License or CLA +- 280 North Inc. (Now Motorola LLC, a subsidiary of Google Inc.) + Copyright (C) 2009 MIT License + diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/LICENSE b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/LICENSE new file mode 100644 index 0000000000..fee08255cb --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/LICENSE @@ -0,0 +1,19 @@ + +Copyright 2009, 2010 Kristopher Michael Kowal. All rights reserved. +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to +deal in the Software without restriction, including without limitation the +rights to use, copy, modify, merge, publish, distribute, sublicense, and/or +sell copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +IN THE SOFTWARE. diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/README.md b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/README.md new file mode 100644 index 0000000000..2972222814 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/README.md @@ -0,0 +1,161 @@ + +`es5-shim.js` and `es5-shim.min.js` monkey-patch a JavaScript context to +contain all EcmaScript 5 methods that can be faithfully emulated with a +legacy JavaScript engine. + +`es5-sham.js` and `es5-sham.min.js` monkey-patch other ES5 methods as +closely as possible. For these methods, as closely as possible to ES5 +is not very close. Many of these shams are intended only to allow code +to be written to ES5 without causing run-time errors in older engines. +In many cases, this means that these shams cause many ES5 methods to +silently fail. Decide carefully whether this is what you want. + + +## Tests + +The tests are written with the Jasmine BDD test framework. +To run the tests, navigate to <root-folder>/tests/. + +In order to run against the shim-code, the tests attempt to kill the current +implementation of the missing methods. This happens in <root-folder>/tests/helpers/h-kill.js. +So in order to run the tests against the build-in methods, invalidate that file somehow +(comment-out, delete the file, delete the script-tag, etc.). + +## Shims + +### Complete tests ### + +* Array.prototype.every +* Array.prototype.filter +* Array.prototype.forEach +* Array.prototype.indexOf +* Array.prototype.lastIndexOf +* Array.prototype.map +* Array.prototype.some +* Array.prototype.reduce +* Array.prototype.reduceRight +* Array.isArray +* Date.now +* Date.prototype.toJSON +* Function.prototype.bind + * /!\ Caveat: the bound function's length is always 0. + * /!\ Caveat: the bound function has a prototype property. + * /!\ Caveat: bound functions do not try too hard to keep you + from manipulating their ``arguments`` and ``caller`` properties. + * /!\ Caveat: bound functions don't have checks in ``call`` and + ``apply`` to avoid executing as a constructor. +* Object.keys +* String.prototype.trim + +### Untested ### + +* Date.parse (for ISO parsing) +* Date.prototype.toISOString + +## Shams + +* /?\ Object.create + + For the case of simply "begetting" an object that + inherits prototypically from another, this should work + fine across legacy engines. + + /!\ Object.create(null) will work only in browsers that + support prototype assignment. This creates an object + that does not have any properties inherited from + Object.prototype. It will silently fail otherwise. + + /!\ The second argument is passed to + Object.defineProperties which will probably fail + silently. + +* /?\ Object.getPrototypeOf + + This will return "undefined" in some cases. It uses + __proto__ if it's available. Failing that, it uses + constructor.prototype, which depends on the constructor + property of the object's prototype having not been + replaced. If your object was created like this, it + won't work: + + function Foo() { + } + Foo.prototype = {}; + + Because the prototype reassignment destroys the + constructor property. + + This will work for all objects that were created using + `Object.create` implemented with this library. + +* /!\ Object.getOwnPropertyNames + + This method uses Object.keys, so it will not be accurate + on legacy engines. + +* Object.isSealed + + Returns "false" in all legacy engines for all objects, + which is conveniently guaranteed to be accurate. + +* Object.isFrozen + + Returns "false" in all legacy engines for all objects, + which is conveniently guaranteed to be accurate. + +* Object.isExtensible + + Works like a charm, by trying very hard to extend the + object then redacting the extension. + +### Fail silently + +* /!\ Object.getOwnPropertyDescriptor + + The behavior of this shim does not conform to ES5. It + should probably not be used at this time, until its + behavior has been reviewed and been confirmed to be + useful in legacy engines. + +* /!\ Object.defineProperty + + This method will silently fail to set "writable", + "enumerable", and "configurable" properties. + + Providing a getter or setter with "get" or "set" on a + descriptor will silently fail on engines that lack + "__defineGetter__" and "__defineSetter__", which include + all versions of IE up to version 8 so far. + + IE 8 provides a version of this method but it only works + on DOM objects. Thus, the shim will not get installed + and attempts to set "value" properties will fail + silently on non-DOM objects. + + https://github.com/kriskowal/es5-shim/issues#issue/5 + +* /!\ Object.defineProperties + + This uses the Object.defineProperty shim + +* Object.seal + + Silently fails on all legacy engines. This should be + fine unless you are depending on the safety and security + provisions of this method, which you cannot possibly + obtain in legacy engines. + +* Object.freeze + + Silently fails on all legacy engines. This should be + fine unless you are depending on the safety and security + provisions of this method, which you cannot possibly + obtain in legacy engines. + +* Object.preventExtensions + + Silently fails on all legacy engines. This should be + fine unless you are depending on the safety and security + provisions of this method, which you cannot possibly + obtain in legacy engines. + diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/component.json b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/component.json new file mode 100644 index 0000000000..975e063b1d --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/component.json @@ -0,0 +1,54 @@ +{ + "name": "es5-shim", + "version": "2.0.0", + "description": "ES5 as implementable on previous engines", + "homepage": "http://github.com/kriskowal/es5-shim/", + "contributors": [ + { + "name": "Kris Kowal", + "email": "kris@cixar.com", + "url": "http://github.com/kriskowal/" + }, + { + "name": "Sami Samhuri", + "email": "sami.samhuri@gmail.com", + "url": "http://samhuri.net/" + }, + { + "name": "Florian Schäfer", + "email": "florian.schaefer@gmail.com", + "url": "http://github.com/fschaefer" + }, + { + "name": "Irakli Gozalishvili", + "email": "rfobic@gmail.com", + "url": "http://jeditoolkit.com" + }, + { + "name": "Kit Cambridge", + "email": "kitcambridge@gmail.com", + "url": "http://kitcambridge.github.com" + } + ], + "bugs": { + "mail": "kris@cixar.com", + "url": "http://github.com/kriskowal/es5-shim/issues" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/kriskowal/es5-shim/raw/master/LICENSE" + } + ], + "main": "es5-shim.js", + "repository": { + "type": "git", + "url": "git://github.com/kriskowal/es5-shim.git" + }, + "engines": { + "node": ">=0.2.0" + }, + "readme": "\n`es5-shim.js` and `es5-shim.min.js` monkey-patch a JavaScript context to\ncontain all EcmaScript 5 methods that can be faithfully emulated with a\nlegacy JavaScript engine.\n\n`es5-sham.js` and `es5-sham.min.js` monkey-patch other ES5 methods as\nclosely as possible. For these methods, as closely as possible to ES5\nis not very close. Many of these shams are intended only to allow code\nto be written to ES5 without causing run-time errors in older engines.\nIn many cases, this means that these shams cause many ES5 methods to\nsilently fail. Decide carefully whether this is what you want.\n\n\n## Tests\n\nThe tests are written with the Jasmine BDD test framework.\nTo run the tests, navigate to <root-folder>/tests/. \n\nIn order to run against the shim-code, the tests attempt to kill the current \nimplementation of the missing methods. This happens in <root-folder>/tests/helpers/h-kill.js.\nSo in order to run the tests against the build-in methods, invalidate that file somehow\n(comment-out, delete the file, delete the script-tag, etc.).\n\n## Shims\n\n### Complete tests ###\n\n* Array.prototype.every\n* Array.prototype.filter\n* Array.prototype.forEach\n* Array.prototype.indexOf\n* Array.prototype.lastIndexOf\n* Array.prototype.map\n* Array.prototype.some\n* Array.prototype.reduce\n* Array.prototype.reduceRight\n* Array.isArray\n* Date.now\n* Date.prototype.toJSON\n* Function.prototype.bind\n * /!\\ Caveat: the bound function's length is always 0.\n * /!\\ Caveat: the bound function has a prototype property.\n * /!\\ Caveat: bound functions do not try too hard to keep you\n from manipulating their ``arguments`` and ``caller`` properties.\n * /!\\ Caveat: bound functions don't have checks in ``call`` and\n ``apply`` to avoid executing as a constructor.\n* Object.keys\n* String.prototype.trim\n\n### Untested ###\n\n* Date.parse (for ISO parsing)\n* Date.prototype.toISOString\n\n## Shams\n\n* /?\\ Object.create\n\n For the case of simply \"begetting\" an object that\n inherits prototypically from another, this should work\n fine across legacy engines.\n\n /!\\ Object.create(null) will work only in browsers that\n support prototype assignment. This creates an object\n that does not have any properties inherited from\n Object.prototype. It will silently fail otherwise.\n\n /!\\ The second argument is passed to\n Object.defineProperties which will probably fail\n silently.\n\n* /?\\ Object.getPrototypeOf\n\n This will return \"undefined\" in some cases. It uses\n __proto__ if it's available. Failing that, it uses\n constructor.prototype, which depends on the constructor\n property of the object's prototype having not been\n replaced. If your object was created like this, it\n won't work:\n\n function Foo() {\n }\n Foo.prototype = {};\n\n Because the prototype reassignment destroys the\n constructor property.\n\n This will work for all objects that were created using\n `Object.create` implemented with this library.\n\n* /!\\ Object.getOwnPropertyNames\n\n This method uses Object.keys, so it will not be accurate\n on legacy engines.\n\n* Object.isSealed\n\n Returns \"false\" in all legacy engines for all objects,\n which is conveniently guaranteed to be accurate.\n\n* Object.isFrozen\n\n Returns \"false\" in all legacy engines for all objects,\n which is conveniently guaranteed to be accurate.\n\n* Object.isExtensible\n\n Works like a charm, by trying very hard to extend the\n object then redacting the extension.\n\n### Fail silently\n\n* /!\\ Object.getOwnPropertyDescriptor\n \n The behavior of this shim does not conform to ES5. It\n should probably not be used at this time, until its\n behavior has been reviewed and been confirmed to be\n useful in legacy engines.\n\n* /!\\ Object.defineProperty\n\n This method will silently fail to set \"writable\",\n \"enumerable\", and \"configurable\" properties.\n \n Providing a getter or setter with \"get\" or \"set\" on a\n descriptor will silently fail on engines that lack\n \"__defineGetter__\" and \"__defineSetter__\", which include\n all versions of IE up to version 8 so far.\n\n IE 8 provides a version of this method but it only works\n on DOM objects. Thus, the shim will not get installed\n and attempts to set \"value\" properties will fail\n silently on non-DOM objects.\n\n https://github.com/kriskowal/es5-shim/issues#issue/5\n\n* /!\\ Object.defineProperties\n\n This uses the Object.defineProperty shim\n\n* Object.seal\n\n Silently fails on all legacy engines. This should be\n fine unless you are depending on the safety and security\n provisions of this method, which you cannot possibly\n obtain in legacy engines.\n\n* Object.freeze\n\n Silently fails on all legacy engines. This should be\n fine unless you are depending on the safety and security\n provisions of this method, which you cannot possibly\n obtain in legacy engines.\n\n* Object.preventExtensions\n\n Silently fails on all legacy engines. This should be\n fine unless you are depending on the safety and security\n provisions of this method, which you cannot possibly\n obtain in legacy engines.\n\n", + "readmeFilename": "README.md", + "_id": "es5-shim@2.0.0" +}
\ No newline at end of file diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.js new file mode 100644 index 0000000000..a1b46cbc1f --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.js @@ -0,0 +1,326 @@ +// Copyright 2009-2012 by contributors, MIT License +// vim: ts=4 sts=4 sw=4 expandtab + +// Module systems magic dance +(function (definition) { + // RequireJS + if (typeof define == "function") { + define(definition); + // YUI3 + } else if (typeof YUI == "function") { + YUI.add("es5-sham", definition); + // CommonJS and <script> + } else { + definition(); + } +})(function () { + +// ES5 15.2.3.2 +// http://es5.github.com/#x15.2.3.2 +if (!Object.getPrototypeOf) { + // https://github.com/kriskowal/es5-shim/issues#issue/2 + // http://ejohn.org/blog/objectgetprototypeof/ + // recommended by fschaefer on github + Object.getPrototypeOf = function getPrototypeOf(object) { + return object.__proto__ || ( + object.constructor + ? object.constructor.prototype + : prototypeOfObject + ); + }; +} + +// ES5 15.2.3.3 +// http://es5.github.com/#x15.2.3.3 +if (!Object.getOwnPropertyDescriptor) { + var ERR_NON_OBJECT = "Object.getOwnPropertyDescriptor called on a non-object: "; + + Object.getOwnPropertyDescriptor = function getOwnPropertyDescriptor(object, property) { + if ((typeof object != "object" && typeof object != "function") || object === null) { + throw new TypeError(ERR_NON_OBJECT + object); + } + // If object does not owns property return undefined immediately. + if (!owns(object, property)) { + return; + } + + // If object has a property then it's for sure both `enumerable` and + // `configurable`. + var descriptor = { enumerable: true, configurable: true }; + + // If JS engine supports accessor properties then property may be a + // getter or setter. + if (supportsAccessors) { + // Unfortunately `__lookupGetter__` will return a getter even + // if object has own non getter property along with a same named + // inherited getter. To avoid misbehavior we temporary remove + // `__proto__` so that `__lookupGetter__` will return getter only + // if it's owned by an object. + var prototype = object.__proto__; + object.__proto__ = prototypeOfObject; + + var getter = lookupGetter(object, property); + var setter = lookupSetter(object, property); + + // Once we have getter and setter we can put values back. + object.__proto__ = prototype; + + if (getter || setter) { + if (getter) { + descriptor.get = getter; + } + if (setter) { + descriptor.set = setter; + } + // If it was accessor property we're done and return here + // in order to avoid adding `value` to the descriptor. + return descriptor; + } + } + + // If we got this far we know that object has an own property that is + // not an accessor so we set it as a value and return descriptor. + descriptor.value = object[property]; + return descriptor; + }; +} + +// ES5 15.2.3.4 +// http://es5.github.com/#x15.2.3.4 +if (!Object.getOwnPropertyNames) { + Object.getOwnPropertyNames = function getOwnPropertyNames(object) { + return Object.keys(object); + }; +} + +// ES5 15.2.3.5 +// http://es5.github.com/#x15.2.3.5 +if (!Object.create) { + Object.create = function create(prototype, properties) { + var object; + if (prototype === null) { + object = { "__proto__": null }; + } else { + if (typeof prototype != "object") { + throw new TypeError("typeof prototype["+(typeof prototype)+"] != 'object'"); + } + var Type = function () {}; + Type.prototype = prototype; + object = new Type(); + // IE has no built-in implementation of `Object.getPrototypeOf` + // neither `__proto__`, but this manually setting `__proto__` will + // guarantee that `Object.getPrototypeOf` will work as expected with + // objects created using `Object.create` + object.__proto__ = prototype; + } + if (properties !== void 0) { + Object.defineProperties(object, properties); + } + return object; + }; +} + +// ES5 15.2.3.6 +// http://es5.github.com/#x15.2.3.6 + +// Patch for WebKit and IE8 standard mode +// Designed by hax <hax.github.com> +// related issue: https://github.com/kriskowal/es5-shim/issues#issue/5 +// IE8 Reference: +// http://msdn.microsoft.com/en-us/library/dd282900.aspx +// http://msdn.microsoft.com/en-us/library/dd229916.aspx +// WebKit Bugs: +// https://bugs.webkit.org/show_bug.cgi?id=36423 + +function doesDefinePropertyWork(object) { + try { + Object.defineProperty(object, "sentinel", {}); + return "sentinel" in object; + } catch (exception) { + // returns falsy + } +} + +// check whether defineProperty works if it's given. Otherwise, +// shim partially. +if (Object.defineProperty) { + var definePropertyWorksOnObject = doesDefinePropertyWork({}); + var definePropertyWorksOnDom = typeof document == "undefined" || + doesDefinePropertyWork(document.createElement("div")); + if (!definePropertyWorksOnObject || !definePropertyWorksOnDom) { + var definePropertyFallback = Object.defineProperty; + } +} + +if (!Object.defineProperty || definePropertyFallback) { + var ERR_NON_OBJECT_DESCRIPTOR = "Property description must be an object: "; + var ERR_NON_OBJECT_TARGET = "Object.defineProperty called on non-object: " + var ERR_ACCESSORS_NOT_SUPPORTED = "getters & setters can not be defined " + + "on this javascript engine"; + + Object.defineProperty = function defineProperty(object, property, descriptor) { + if ((typeof object != "object" && typeof object != "function") || object === null) { + throw new TypeError(ERR_NON_OBJECT_TARGET + object); + } + if ((typeof descriptor != "object" && typeof descriptor != "function") || descriptor === null) { + throw new TypeError(ERR_NON_OBJECT_DESCRIPTOR + descriptor); + } + // make a valiant attempt to use the real defineProperty + // for I8's DOM elements. + if (definePropertyFallback) { + try { + return definePropertyFallback.call(Object, object, property, descriptor); + } catch (exception) { + // try the shim if the real one doesn't work + } + } + + // If it's a data property. + if (owns(descriptor, "value")) { + // fail silently if "writable", "enumerable", or "configurable" + // are requested but not supported + /* + // alternate approach: + if ( // can't implement these features; allow false but not true + !(owns(descriptor, "writable") ? descriptor.writable : true) || + !(owns(descriptor, "enumerable") ? descriptor.enumerable : true) || + !(owns(descriptor, "configurable") ? descriptor.configurable : true) + ) + throw new RangeError( + "This implementation of Object.defineProperty does not " + + "support configurable, enumerable, or writable." + ); + */ + + if (supportsAccessors && (lookupGetter(object, property) || + lookupSetter(object, property))) + { + // As accessors are supported only on engines implementing + // `__proto__` we can safely override `__proto__` while defining + // a property to make sure that we don't hit an inherited + // accessor. + var prototype = object.__proto__; + object.__proto__ = prototypeOfObject; + // Deleting a property anyway since getter / setter may be + // defined on object itself. + delete object[property]; + object[property] = descriptor.value; + // Setting original `__proto__` back now. + object.__proto__ = prototype; + } else { + object[property] = descriptor.value; + } + } else { + if (!supportsAccessors) { + throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); + } + // If we got that far then getters and setters can be defined !! + if (owns(descriptor, "get")) { + defineGetter(object, property, descriptor.get); + } + if (owns(descriptor, "set")) { + defineSetter(object, property, descriptor.set); + } + } + return object; + }; +} + +// ES5 15.2.3.7 +// http://es5.github.com/#x15.2.3.7 +if (!Object.defineProperties) { + Object.defineProperties = function defineProperties(object, properties) { + for (var property in properties) { + if (owns(properties, property) && property != "__proto__") { + Object.defineProperty(object, property, properties[property]); + } + } + return object; + }; +} + +// ES5 15.2.3.8 +// http://es5.github.com/#x15.2.3.8 +if (!Object.seal) { + Object.seal = function seal(object) { + // this is misleading and breaks feature-detection, but + // allows "securable" code to "gracefully" degrade to working + // but insecure code. + return object; + }; +} + +// ES5 15.2.3.9 +// http://es5.github.com/#x15.2.3.9 +if (!Object.freeze) { + Object.freeze = function freeze(object) { + // this is misleading and breaks feature-detection, but + // allows "securable" code to "gracefully" degrade to working + // but insecure code. + return object; + }; +} + +// detect a Rhino bug and patch it +try { + Object.freeze(function () {}); +} catch (exception) { + Object.freeze = (function freeze(freezeObject) { + return function freeze(object) { + if (typeof object == "function") { + return object; + } else { + return freezeObject(object); + } + }; + })(Object.freeze); +} + +// ES5 15.2.3.10 +// http://es5.github.com/#x15.2.3.10 +if (!Object.preventExtensions) { + Object.preventExtensions = function preventExtensions(object) { + // this is misleading and breaks feature-detection, but + // allows "securable" code to "gracefully" degrade to working + // but insecure code. + return object; + }; +} + +// ES5 15.2.3.11 +// http://es5.github.com/#x15.2.3.11 +if (!Object.isSealed) { + Object.isSealed = function isSealed(object) { + return false; + }; +} + +// ES5 15.2.3.12 +// http://es5.github.com/#x15.2.3.12 +if (!Object.isFrozen) { + Object.isFrozen = function isFrozen(object) { + return false; + }; +} + +// ES5 15.2.3.13 +// http://es5.github.com/#x15.2.3.13 +if (!Object.isExtensible) { + Object.isExtensible = function isExtensible(object) { + // 1. If Type(O) is not Object throw a TypeError exception. + if (Object(object) !== object) { + throw new TypeError(); // TODO message + } + // 2. Return the Boolean value of the [[Extensible]] internal property of O. + var name = ''; + while (owns(object, name)) { + name += '?'; + } + object[name] = true; + var returnValue = owns(object, name); + delete object[name]; + return returnValue; + }; +} + +}); diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.min.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.min.js new file mode 100644 index 0000000000..a378503583 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-sham.min.js @@ -0,0 +1,6 @@ +(function(d){"function"==typeof define?define(d):"function"==typeof YUI?YUI.add("es5-sham",d):d()})(function(){function d(a){try{return Object.defineProperty(a,"sentinel",{}),"sentinel"in a}catch(c){}}Object.getPrototypeOf||(Object.getPrototypeOf=function(a){return a.__proto__||(a.constructor?a.constructor.prototype:prototypeOfObject)});Object.getOwnPropertyDescriptor||(Object.getOwnPropertyDescriptor=function(a,c){if(typeof a!="object"&&typeof a!="function"||a===null)throw new TypeError("Object.getOwnPropertyDescriptor called on a non-object: "+ +a);if(owns(a,c)){var b={enumerable:true,configurable:true};if(supportsAccessors){var d=a.__proto__;a.__proto__=prototypeOfObject;var f=lookupGetter(a,c),e=lookupSetter(a,c);a.__proto__=d;if(f||e){if(f)b.get=f;if(e)b.set=e;return b}}b.value=a[c];return b}});Object.getOwnPropertyNames||(Object.getOwnPropertyNames=function(a){return Object.keys(a)});Object.create||(Object.create=function(a,c){var b;if(a===null)b={__proto__:null};else{if(typeof a!="object")throw new TypeError("typeof prototype["+typeof a+ +"] != 'object'");b=function(){};b.prototype=a;b=new b;b.__proto__=a}c!==void 0&&Object.defineProperties(b,c);return b});if(Object.defineProperty){var g=d({}),h="undefined"==typeof document||d(document.createElement("div"));if(!g||!h)var e=Object.defineProperty}if(!Object.defineProperty||e)Object.defineProperty=function(a,c,b){if(typeof a!="object"&&typeof a!="function"||a===null)throw new TypeError("Object.defineProperty called on non-object: "+a);if(typeof b!="object"&&typeof b!="function"||b=== +null)throw new TypeError("Property description must be an object: "+b);if(e)try{return e.call(Object,a,c,b)}catch(d){}if(owns(b,"value"))if(supportsAccessors&&(lookupGetter(a,c)||lookupSetter(a,c))){var f=a.__proto__;a.__proto__=prototypeOfObject;delete a[c];a[c]=b.value;a.__proto__=f}else a[c]=b.value;else{if(!supportsAccessors)throw new TypeError("getters & setters can not be defined on this javascript engine");owns(b,"get")&&defineGetter(a,c,b.get);owns(b,"set")&&defineSetter(a,c,b.set)}return a}; +Object.defineProperties||(Object.defineProperties=function(a,c){for(var b in c)owns(c,b)&&b!="__proto__"&&Object.defineProperty(a,b,c[b]);return a});Object.seal||(Object.seal=function(a){return a});Object.freeze||(Object.freeze=function(a){return a});try{Object.freeze(function(){})}catch(j){var i=Object.freeze;Object.freeze=function(a){return typeof a=="function"?a:i(a)}}Object.preventExtensions||(Object.preventExtensions=function(a){return a});Object.isSealed||(Object.isSealed=function(){return false}); +Object.isFrozen||(Object.isFrozen=function(){return false});Object.isExtensible||(Object.isExtensible=function(a){if(Object(a)!==a)throw new TypeError;for(var c="";owns(a,c);)c=c+"?";a[c]=true;var b=owns(a,c);delete a[c];return b})}); diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.js new file mode 100644 index 0000000000..d59197db45 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.js @@ -0,0 +1,778 @@ +// Copyright 2009-2012 by contributors, MIT License +// vim: ts=4 sts=4 sw=4 expandtab + +// Module systems magic dance +(function (definition) { + // RequireJS + if (typeof define == "function") { + define(definition); + // YUI3 + } else if (typeof YUI == "function") { + YUI.add("es5", definition); + // CommonJS and <script> + } else { + definition(); + } +})(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/ + */ + +// +// Function +// ======== +// + +// ES-5 15.3.4.5 +// http://es5.github.com/#x15.3.4.5 + +if (!Function.prototype.bind) { + Function.prototype.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 (typeof target != "function") { + 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 = 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 = 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 F = function(){}; + F.prototype = target.prototype; + var self = new F; + + var result = target.apply( + self, + args.concat(slice.call(arguments)) + ); + if (Object(result) === result) { + return result; + } + return self; + + } 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, + args.concat(slice.call(arguments)) + ); + + } + + }; + // XXX bound.length is never writable, so don't even try + // + // 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. + // 17. Set the attributes of the length own property of F to the values + // specified in 15.3.5.1. + + // 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; + }; +} + +// Shortcut to an often accessed properties, in order to avoid multiple +// dereference that costs universally. +// _Please note: Shortcuts are defined after `Function.prototype.bind` as we +// us it in defining shortcuts. +var call = Function.prototype.call; +var prototypeOfArray = Array.prototype; +var prototypeOfObject = Object.prototype; +var slice = prototypeOfArray.slice; +// Having a toString local variable name breaks in Opera so use _toString. +var _toString = call.bind(prototypeOfObject.toString); +var owns = call.bind(prototypeOfObject.hasOwnProperty); + +// If JS engine supports accessors creating shortcuts. +var defineGetter; +var defineSetter; +var lookupGetter; +var lookupSetter; +var supportsAccessors; +if ((supportsAccessors = owns(prototypeOfObject, "__defineGetter__"))) { + defineGetter = call.bind(prototypeOfObject.__defineGetter__); + defineSetter = call.bind(prototypeOfObject.__defineSetter__); + lookupGetter = call.bind(prototypeOfObject.__lookupGetter__); + lookupSetter = call.bind(prototypeOfObject.__lookupSetter__); +} + +// +// Array +// ===== +// + +// ES5 15.4.3.2 +// http://es5.github.com/#x15.4.3.2 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/isArray +if (!Array.isArray) { + Array.isArray = function isArray(obj) { + return _toString(obj) == "[object Array]"; + }; +} + +// 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 +if (!Array.prototype.forEach) { + Array.prototype.forEach = function forEach(fun /*, thisp*/) { + var self = toObject(this), + thisp = arguments[1], + i = -1, + length = self.length >>> 0; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(); // TODO message + } + + while (++i < length) { + if (i in self) { + // Invoke the callback function with call, passing arguments: + // context, property value, property key, thisArg object context + fun.call(thisp, self[i], i, self); + } + } + }; +} + +// 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 +if (!Array.prototype.map) { + Array.prototype.map = function map(fun /*, thisp*/) { + var self = toObject(this), + length = self.length >>> 0, + result = Array(length), + thisp = arguments[1]; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self) + result[i] = fun.call(thisp, self[i], i, self); + } + return result; + }; +} + +// 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 +if (!Array.prototype.filter) { + Array.prototype.filter = function filter(fun /*, thisp */) { + var self = toObject(this), + length = self.length >>> 0, + result = [], + value, + thisp = arguments[1]; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self) { + value = self[i]; + if (fun.call(thisp, value, i, self)) { + result.push(value); + } + } + } + return result; + }; +} + +// ES5 15.4.4.16 +// http://es5.github.com/#x15.4.4.16 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/every +if (!Array.prototype.every) { + Array.prototype.every = function every(fun /*, thisp */) { + var self = toObject(this), + length = self.length >>> 0, + thisp = arguments[1]; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self && !fun.call(thisp, self[i], i, self)) { + return false; + } + } + return true; + }; +} + +// ES5 15.4.4.17 +// http://es5.github.com/#x15.4.4.17 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/some +if (!Array.prototype.some) { + Array.prototype.some = function some(fun /*, thisp */) { + var self = toObject(this), + length = self.length >>> 0, + thisp = arguments[1]; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + for (var i = 0; i < length; i++) { + if (i in self && fun.call(thisp, self[i], i, self)) { + return true; + } + } + return false; + }; +} + +// 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 +if (!Array.prototype.reduce) { + Array.prototype.reduce = function reduce(fun /*, initial*/) { + var self = toObject(this), + length = self.length >>> 0; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + // no value to return if no initial value and an empty array + if (!length && 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 = fun.call(void 0, result, self[i], i, self); + } + } + + return result; + }; +} + +// 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 +if (!Array.prototype.reduceRight) { + Array.prototype.reduceRight = function reduceRight(fun /*, initial*/) { + var self = toObject(this), + length = self.length >>> 0; + + // If no callback function or if callback is not a callable function + if (_toString(fun) != "[object Function]") { + throw new TypeError(fun + " is not a function"); + } + + // no value to return if no initial value, empty array + if (!length && arguments.length == 1) { + throw new TypeError('reduceRight of empty array with no initial value'); + } + + var result, 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); + } + + do { + if (i in this) { + result = fun.call(void 0, result, self[i], i, self); + } + } while (i--); + + return result; + }; +} + +// ES5 15.4.4.14 +// http://es5.github.com/#x15.4.4.14 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/indexOf +if (!Array.prototype.indexOf) { + Array.prototype.indexOf = function indexOf(sought /*, fromIndex */ ) { + var self = toObject(this), + length = self.length >>> 0; + + if (!length) { + return -1; + } + + var i = 0; + if (arguments.length > 1) { + i = toInteger(arguments[1]); + } + + // handle negative indices + i = i >= 0 ? i : Math.max(0, length + i); + for (; i < length; i++) { + if (i in self && self[i] === sought) { + return i; + } + } + return -1; + }; +} + +// ES5 15.4.4.15 +// http://es5.github.com/#x15.4.4.15 +// https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Array/lastIndexOf +if (!Array.prototype.lastIndexOf) { + Array.prototype.lastIndexOf = function lastIndexOf(sought /*, fromIndex */) { + var self = toObject(this), + length = self.length >>> 0; + + if (!length) { + return -1; + } + var i = length - 1; + if (arguments.length > 1) { + i = Math.min(i, toInteger(arguments[1])); + } + // handle negative indices + i = i >= 0 ? i : length - Math.abs(i); + for (; i >= 0; i--) { + if (i in self && sought === self[i]) { + return i; + } + } + return -1; + }; +} + +// +// Object +// ====== +// + +// ES5 15.2.3.14 +// http://es5.github.com/#x15.2.3.14 +if (!Object.keys) { + // http://whattheheadsaid.com/2010/10/a-safer-object-keys-compatibility-implementation + var hasDontEnumBug = true, + dontEnums = [ + "toString", + "toLocaleString", + "valueOf", + "hasOwnProperty", + "isPrototypeOf", + "propertyIsEnumerable", + "constructor" + ], + dontEnumsLength = dontEnums.length; + + for (var key in {"toString": null}) { + hasDontEnumBug = false; + } + + Object.keys = function keys(object) { + + if ((typeof object != "object" && typeof object != "function") || object === null) { + throw new TypeError("Object.keys called on a non-object"); + } + + var keys = []; + for (var name in object) { + if (owns(object, name)) { + keys.push(name); + } + } + + if (hasDontEnumBug) { + for (var i = 0, ii = dontEnumsLength; i < ii; i++) { + var dontEnum = dontEnums[i]; + if (owns(object, dontEnum)) { + keys.push(dontEnum); + } + } + } + return keys; + }; + +} + +// +// 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. +if (!Date.prototype.toISOString || (new Date(-62198755200000).toISOString().indexOf('-000001') === -1)) { + Date.prototype.toISOString = function toISOString() { + var result, length, value, year; + if (!isFinite(this)) { + throw new RangeError("Date.prototype.toISOString called on non-finite value."); + } + + // the date time string format is specified in 15.9.1.15. + result = [this.getUTCMonth() + 1, this.getUTCDate(), + this.getUTCHours(), this.getUTCMinutes(), this.getUTCSeconds()]; + year = this.getUTCFullYear(); + year = (year < 0 ? '-' : (year > 9999 ? '+' : '')) + ('00000' + Math.abs(year)).slice(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 + "-" + result.slice(0, 2).join("-") + "T" + result.slice(2).join(":") + "." + + ("000" + this.getUTCMilliseconds()).slice(-3) + "Z"; + } +} + +// ES5 15.9.4.4 +// http://es5.github.com/#x15.9.4.4 +if (!Date.now) { + Date.now = function now() { + return new Date().getTime(); + }; +} + +// 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). +if (!Date.prototype.toJSON) { + 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 ToPrimitive(O, hint Number). + // 3. If tv is a Number and is not finite, return null. + // XXX + // 4. Let toISO be the result of calling the [[Get]] internal method of + // O with argument "toISOString". + // 5. If IsCallable(toISO) is false, throw a TypeError exception. + if (typeof this.toISOString != "function") { + 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 this.toISOString(); + + // 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 +if (!Date.parse || Date.parse("+275760-09-13T00:00:00.000Z") !== 8.64e15) { + // XXX global assignment won't work in embeddings that use + // an alternate object for the context. + Date = (function(NativeDate) { + + // Date.length === 7 + var Date = function Date(Y, M, D, h, m, s, ms) { + var length = arguments.length; + if (this instanceof NativeDate) { + var date = length == 1 && String(Y) === Y ? // isString(Y) + // We explicitly pass it through parse: + new NativeDate(Date.parse(Y)) : + // We have to manually make calls depending on argument + // length here + length >= 7 ? new NativeDate(Y, M, D, h, m, s, ms) : + length >= 6 ? new NativeDate(Y, M, D, h, m, s) : + 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(); + // Prevent mixups with unfixed Date object + date.constructor = Date; + return date; + } + return NativeDate.apply(this, arguments); + }; + + // 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{3}))?" + // 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 + ")" + + ")?)?)?)?" + + "$"); + + // Copy any custom methods a 3rd party library may have added + for (var key in NativeDate) { + Date[key] = NativeDate[key]; + } + + // Copy "native" methods explicitly; they may be non-enumerable + Date.now = NativeDate.now; + Date.UTC = NativeDate.UTC; + Date.prototype = NativeDate.prototype; + Date.prototype.constructor = Date; + + // Upgrade Date.parse to handle simplified ISO 8601 strings + Date.parse = function parse(string) { + var match = isoDateExpression.exec(string); + if (match) { + match.shift(); // kill match[0], the full match + // parse months, days, hours, minutes, seconds, and milliseconds + for (var i = 1; i < 7; i++) { + // provide default values if necessary + match[i] = +(match[i] || (i < 3 ? 1 : 0)); + // match[1] is the month. Months are 0-11 in JavaScript + // `Date` objects, but 1-12 in ISO notation, so we + // decrement. + if (i == 1) { + match[i]--; + } + } + + // parse the UTC offset component + var minuteOffset = +match.pop(), hourOffset = +match.pop(), sign = match.pop(); + + // compute the explicit time zone offset if specified + var offset = 0; + if (sign) { + // detect invalid offsets and return early + if (hourOffset > 23 || minuteOffset > 59) { + return NaN; + } + + // express the provided time zone offset in minutes. The offset is + // negative for time zones west of UTC; positive otherwise. + offset = (hourOffset * 60 + minuteOffset) * 6e4 * (sign == "+" ? -1 : 1); + } + + // Date.UTC for years between 0 and 99 converts year to 1900 + year + // The Gregorian calendar has a 400-year cycle, so + // to Date.UTC(year + 400, .... ) - 12622780800000 == Date.UTC(year, ...), + // where 12622780800000 - number of milliseconds in Gregorian calendar 400 years + var year = +match[0]; + if (0 <= year && year <= 99) { + match[0] = year + 400; + return NativeDate.UTC.apply(this, match) + offset - 12622780800000; + } + + // compute a new UTC date value, accounting for the optional offset + return NativeDate.UTC.apply(this, match) + offset; + } + return NativeDate.parse.apply(this, arguments); + }; + + return Date; + })(Date); +} + +// +// String +// ====== +// + +// ES5 15.5.4.20 +// http://es5.github.com/#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"; +if (!String.prototype.trim || ws.trim()) { + // http://blog.stevenlevithan.com/archives/faster-trim-javascript + // http://perfectionkills.com/whitespace-deviations/ + ws = "[" + ws + "]"; + var trimBeginRegexp = new RegExp("^" + ws + ws + "*"), + trimEndRegexp = new RegExp(ws + ws + "*$"); + String.prototype.trim = function trim() { + if (this === undefined || this === null) { + throw new TypeError("can't convert "+this+" to object"); + } + return String(this).replace(trimBeginRegexp, "").replace(trimEndRegexp, ""); + }; +} + +// +// Util +// ====== +// + +// ES5 9.4 +// http://es5.github.com/#x9.4 +// http://jsperf.com/to-integer +var toInteger = function (n) { + n = +n; + if (n !== n) { // isNaN + n = 0; + } else if (n !== 0 && n !== (1/0) && n !== -(1/0)) { + n = (n > 0 || -1) * Math.floor(Math.abs(n)); + } + return n; +}; + +var prepareString = "a"[0] != "a"; + // ES5 9.9 + // http://es5.github.com/#x9.9 +var toObject = function (o) { + if (o == null) { // this matches both null and undefined + throw new TypeError("can't convert "+o+" to object"); + } + // If the implementation doesn't support by-index access of + // string characters (ex. IE < 9), split the string + if (prepareString && typeof o == "string" && o) { + return o.split(""); + } + return Object(o); +}; + +}); diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.min.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.min.js new file mode 100644 index 0000000000..2764d6eb14 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/es5-shim.min.js @@ -0,0 +1,13 @@ +(function(f){"function"==typeof define?define(f):"function"==typeof YUI?YUI.add("es5",f):f()})(function(){Function.prototype.bind||(Function.prototype.bind=function(d){var c=this;if("function"!=typeof c)throw new TypeError("Function.prototype.bind called on incompatible "+c);var a=n.call(arguments,1),b=function(){if(this instanceof b){var e=function(){};e.prototype=c.prototype;var e=new e,i=c.apply(e,a.concat(n.call(arguments)));return Object(i)===i?i:e}return c.apply(d,a.concat(n.call(arguments)))}; +return b});var f=Function.prototype.call,m=Object.prototype,n=Array.prototype.slice,l=f.bind(m.toString),o=f.bind(m.hasOwnProperty);o(m,"__defineGetter__")&&(f.bind(m.__defineGetter__),f.bind(m.__defineSetter__),f.bind(m.__lookupGetter__),f.bind(m.__lookupSetter__));Array.isArray||(Array.isArray=function(d){return l(d)=="[object Array]"});Array.prototype.forEach||(Array.prototype.forEach=function(d,c){var a=j(this),b=-1,e=a.length>>>0;if(l(d)!="[object Function]")throw new TypeError;for(;++b<e;)b in +a&&d.call(c,a[b],b,a)});Array.prototype.map||(Array.prototype.map=function(d,c){var a=j(this),b=a.length>>>0,e=Array(b);if(l(d)!="[object Function]")throw new TypeError(d+" is not a function");for(var i=0;i<b;i++)i in a&&(e[i]=d.call(c,a[i],i,a));return e});Array.prototype.filter||(Array.prototype.filter=function(d,c){var a=j(this),b=a.length>>>0,e=[],i;if(l(d)!="[object Function]")throw new TypeError(d+" is not a function");for(var f=0;f<b;f++)if(f in a){i=a[f];d.call(c,i,f,a)&&e.push(i)}return e}); +Array.prototype.every||(Array.prototype.every=function(d,c){var a=j(this),b=a.length>>>0;if(l(d)!="[object Function]")throw new TypeError(d+" is not a function");for(var e=0;e<b;e++)if(e in a&&!d.call(c,a[e],e,a))return false;return true});Array.prototype.some||(Array.prototype.some=function(d,c){var a=j(this),b=a.length>>>0;if(l(d)!="[object Function]")throw new TypeError(d+" is not a function");for(var e=0;e<b;e++)if(e in a&&d.call(c,a[e],e,a))return true;return false});Array.prototype.reduce|| +(Array.prototype.reduce=function(d){var c=j(this),a=c.length>>>0;if(l(d)!="[object Function]")throw new TypeError(d+" is not a function");if(!a&&arguments.length==1)throw new TypeError("reduce of empty array with no initial value");var b=0,e;if(arguments.length>=2)e=arguments[1];else{do{if(b in c){e=c[b++];break}if(++b>=a)throw new TypeError("reduce of empty array with no initial value");}while(1)}for(;b<a;b++)b in c&&(e=d.call(void 0,e,c[b],b,c));return e});Array.prototype.reduceRight||(Array.prototype.reduceRight= +function(d){var c=j(this),a=c.length>>>0;if(l(d)!="[object Function]")throw new TypeError(d+" is not a function");if(!a&&arguments.length==1)throw new TypeError("reduceRight of empty array with no initial value");var b,a=a-1;if(arguments.length>=2)b=arguments[1];else{do{if(a in c){b=c[a--];break}if(--a<0)throw new TypeError("reduceRight of empty array with no initial value");}while(1)}do a in this&&(b=d.call(void 0,b,c[a],a,c));while(a--);return b});Array.prototype.indexOf||(Array.prototype.indexOf= +function(d){var c=j(this),a=c.length>>>0;if(!a)return-1;var b=0;arguments.length>1&&(b=p(arguments[1]));for(b=b>=0?b:Math.max(0,a+b);b<a;b++)if(b in c&&c[b]===d)return b;return-1});Array.prototype.lastIndexOf||(Array.prototype.lastIndexOf=function(d){var c=j(this),a=c.length>>>0;if(!a)return-1;var b=a-1;arguments.length>1&&(b=Math.min(b,p(arguments[1])));for(b=b>=0?b:a-Math.abs(b);b>=0;b--)if(b in c&&d===c[b])return b;return-1});if(!Object.keys){var q=!0,r="toString toLocaleString valueOf hasOwnProperty isPrototypeOf propertyIsEnumerable constructor".split(" "), +s=r.length,t;for(t in{toString:null})q=!1;Object.keys=function(d){if(typeof d!="object"&&typeof d!="function"||d===null)throw new TypeError("Object.keys called on a non-object");var c=[],a;for(a in d)o(d,a)&&c.push(a);if(q)for(a=0;a<s;a++){var b=r[a];o(d,b)&&c.push(b)}return c}}if(!Date.prototype.toISOString||-1===(new Date(-621987552E5)).toISOString().indexOf("-000001"))Date.prototype.toISOString=function(){var d,c,a,b;if(!isFinite(this))throw new RangeError("Date.prototype.toISOString called on non-finite value."); +d=[this.getUTCMonth()+1,this.getUTCDate(),this.getUTCHours(),this.getUTCMinutes(),this.getUTCSeconds()];b=this.getUTCFullYear();b=(b<0?"-":b>9999?"+":"")+("00000"+Math.abs(b)).slice(0<=b&&b<=9999?-4:-6);for(c=d.length;c--;){a=d[c];a<10&&(d[c]="0"+a)}return b+"-"+d.slice(0,2).join("-")+"T"+d.slice(2).join(":")+"."+("000"+this.getUTCMilliseconds()).slice(-3)+"Z"};Date.now||(Date.now=function(){return(new Date).getTime()});Date.prototype.toJSON||(Date.prototype.toJSON=function(){if(typeof this.toISOString!= +"function")throw new TypeError("toISOString property is not callable");return this.toISOString()});if(!Date.parse||864E13!==Date.parse("+275760-09-13T00:00:00.000Z")){var g=Date,f=function c(a,b,e,f,h,j,l){var k=arguments.length;if(this instanceof g){k=k==1&&String(a)===a?new g(c.parse(a)):k>=7?new g(a,b,e,f,h,j,l):k>=6?new g(a,b,e,f,h,j):k>=5?new g(a,b,e,f,h):k>=4?new g(a,b,e,f):k>=3?new g(a,b,e):k>=2?new g(a,b):k>=1?new g(a):new g;k.constructor=c;return k}return g.apply(this,arguments)},u=RegExp("^(\\d{4}|[+-]\\d{6})(?:-(\\d{2})(?:-(\\d{2})(?:T(\\d{2}):(\\d{2})(?::(\\d{2})(?:\\.(\\d{3}))?)?(?:Z|(?:([-+])(\\d{2}):(\\d{2})))?)?)?)?$"), +h;for(h in g)f[h]=g[h];f.now=g.now;f.UTC=g.UTC;f.prototype=g.prototype;f.prototype.constructor=f;f.parse=function(c){var a=u.exec(c);if(a){a.shift();for(var b=1;b<7;b++){a[b]=+(a[b]||(b<3?1:0));b==1&&a[b]--}var e=+a.pop(),f=+a.pop(),h=a.pop(),b=0;if(h){if(f>23||e>59)return NaN;b=(f*60+e)*6E4*(h=="+"?-1:1)}e=+a[0];if(0<=e&&e<=99){a[0]=e+400;return g.UTC.apply(this,a)+b-126227808E5}return g.UTC.apply(this,a)+b}return g.parse.apply(this,arguments)};Date=f}h="\t\n\x0B\f\r \u00a0\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000\u2028\u2029\ufeff"; +if(!String.prototype.trim||h.trim()){h="["+h+"]";var v=RegExp("^"+h+h+"*"),w=RegExp(h+h+"*$");String.prototype.trim=function(){if(this===void 0||this===null)throw new TypeError("can't convert "+this+" to object");return String(this).replace(v,"").replace(w,"")}}var p=function(c){c=+c;c!==c?c=0:c!==0&&(c!==1/0&&c!==-(1/0))&&(c=(c>0||-1)*Math.floor(Math.abs(c)));return c},x="a"!="a"[0],j=function(c){if(c==null)throw new TypeError("can't convert "+c+" to object");return x&&typeof c=="string"&&c?c.split(""): +Object(c)}}); diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/package.json b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/package.json new file mode 100644 index 0000000000..82ccae3e6a --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/package.json @@ -0,0 +1,31 @@ +{ + "name": "es5-shim", + "version": "2.0.0", + "description": "ES5 as implementable on previous engines", + "homepage": "http://github.com/kriskowal/es5-shim/", + "contributors": [ + "Kris Kowal <kris@cixar.com> (http://github.com/kriskowal/)", + "Sami Samhuri <sami.samhuri@gmail.com> (http://samhuri.net/)", + "Florian Schäfer <florian.schaefer@gmail.com> (http://github.com/fschaefer)", + "Irakli Gozalishvili <rfobic@gmail.com> (http://jeditoolkit.com)", + "Kit Cambridge <kitcambridge@gmail.com> (http://kitcambridge.github.com)" + ], + "bugs": { + "mail": "kris@cixar.com", + "url": "http://github.com/kriskowal/es5-shim/issues" + }, + "licenses": [ + { + "type": "MIT", + "url": "http://github.com/kriskowal/es5-shim/raw/master/LICENSE" + } + ], + "main": "es5-shim.js", + "repository": { + "type": "git", + "url": "http://github.com/kriskowal/es5-shim.git" + }, + "engines": { + "node": ">=0.2.0" + } +} diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-kill.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-kill.js new file mode 100644 index 0000000000..60b418023f --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-kill.js @@ -0,0 +1,59 @@ +// This methods allows the killing of built-in functions, +// so the shim can take over with that implementation +var HLP = (function() { + "use strict"; + var kill; + + kill = function(_class, methods) { + /*if(!Array.isArray(methods)) + return;*/ + if(!_class.originals) + _class.originals = {}; + + for (var i = 0, len = methods.length; i < len; i++) { + var obj = methods[i]; + _class.originals[obj] = _class[obj]; + delete _class[obj]; + if (obj in _class) { + // try something more aggressive since V8 at least + // appears to ignore the delete. + _class[obj] = null; + if (_class[obj]) { + console.log("Couln't overwrite", obj, "of", _class); + } + } + } + }; + return { kill: kill }; +}()); + +HLP.kill(Function.prototype, [ + 'bind' +]); + +HLP.kill(Array, [ + 'isArray' +]); + +HLP.kill(String.prototype, [ + "trim" +]); + +HLP.kill(Object, [ + 'keys' +]); + +HLP.kill(Date, [ + 'now', 'parse' +]); + +HLP.kill(Date.prototype, [ + "toJSON", "toISOString" +]); + +HLP.kill(Array.prototype, [ + 'forEach', 'some', 'every', + 'indexOf', 'lastIndexOf', + 'map', 'filter', + 'reduce', 'reduceRight' +]); diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-matchers.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-matchers.js new file mode 100644 index 0000000000..dda7513a5f --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h-matchers.js @@ -0,0 +1,34 @@ +beforeEach(function() { + this.addMatchers({ + toExactlyMatch: function(expected) { + var a1, a2, + l, i, + key, + actual = this.actual; + + var getKeys = function(o) { + var a = []; + for(key in o) { + if(o.hasOwnProperty(key)) { + a.push(key); + } + } + return a; + } + 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; + } + }) +}); diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h.js new file mode 100644 index 0000000000..ede51ef673 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/helpers/h.js @@ -0,0 +1,3 @@ +function implement() { + throw 'Not implemented'; +}
\ No newline at end of file diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/index.html b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/index.html new file mode 100644 index 0000000000..e2bf213f39 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/index.html @@ -0,0 +1,62 @@ +<!DOCTYPE HTML> +<html> +<head> + <title>Jasmine Spec Runner</title> + + <link rel="shortcut icon" type="image/png" href="lib/jasmine_favicon.png"> + + <link rel="stylesheet" type="text/css" href="lib/jasmine.css"> + <script type="text/javascript" src="lib/jasmine.js"></script> + <script type="text/javascript" src="lib/jasmine-html.js"></script> + <script type="text/javascript" src="lib/json2.js"></script> + + <!-- include helper files here... --> + <script src="helpers/h.js"></script> + <script src="helpers/h-kill.js"></script> + <script src="helpers/h-matchers.js"></script> + + <!-- include source files here... --> + <script src="../es5-shim.js"></script> + + <!-- include spec files here... --> + <script src="spec/s-array.js"></script> + <script src="spec/s-function.js"></script> + <script src="spec/s-string.js"></script> + <script src="spec/s-object.js"></script> + <script src="spec/s-date.js"></script> + + + <script type="text/javascript"> + (function() { + var jasmineEnv = jasmine.getEnv(); + jasmineEnv.updateInterval = 1000; + + var trivialReporter = new jasmine.TrivialReporter(); + + jasmineEnv.addReporter(trivialReporter); + + jasmineEnv.specFilter = function(spec) { + return trivialReporter.specFilter(spec); + }; + + var currentWindowOnload = window.onload; + + window.onload = function() { + if (currentWindowOnload) { + currentWindowOnload(); + } + execJasmine(); + }; + + function execJasmine() { + jasmineEnv.execute(); + } + + })(); + </script> + +</head> + +<body> +</body> +</html> diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine-html.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine-html.js new file mode 100644 index 0000000000..73834010f6 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine-html.js @@ -0,0 +1,190 @@ +jasmine.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; +}; diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.css b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.css new file mode 100644 index 0000000000..6583fe7c66 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.css @@ -0,0 +1,166 @@ +body { + 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; +} diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.js new file mode 100644 index 0000000000..70d7d25e18 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine.js @@ -0,0 +1,2477 @@ +var isCommonJS = typeof window == "undefined"; + +/** + * 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 <code>jasmine.undefined</code> instead of <code>undefined</code>, since <code>undefined</code> 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; + +/** + * Default timeout interval in milliseconds for waitsFor() blocks. + */ +jasmine.DEFAULT_TIMEOUT_INTERVAL = 5000; + +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); +}; + +/** + * 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 <b>not</b> 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 <code>jasmine.log</code> 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 + * @returns 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 <em>disabled</em> 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 + */ +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, '<') + .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.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 instanceof jasmine.Matchers.Any) { + return a.matches(b); + } + + if (b instanceof jasmine.Matchers.Any) { + 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 (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) { + 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.toNotEqual() 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 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() { + if (this.actual.callCount === 0) { + // todo: what should the failure message for .not.toHaveBeenCalledWith() be? is this right? test better. [xw] + return [ + "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but it was never called.", + "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but it was." + ]; + } else { + return [ + "Expected spy " + this.actual.identity + " to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall), + "Expected spy " + this.actual.identity + " not to have been called with " + jasmine.pp(expectedArgs) + " but was called with " + jasmine.pp(this.actual.argsForCall) + ]; + } + }; + + 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.toNotContain() 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 + */ +jasmine.Matchers.prototype.toBeCloseTo = function(expected, precision) { + if (!(precision === 0)) { + precision = precision || 2; + } + var multiplier = Math.pow(10, precision); + var actual = Math.round(this.actual * multiplier); + expected = Math.round(expected * multiplier); + return expected == actual; +}; + +/** + * 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.matches = 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.toString = function() { + return '<jasmine.any(' + this.expectedClass + ')>'; +}; + +/** + * @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 <b>everything</b> 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) { + if (this.ppNestLevel_ > 40) { + throw new Error('jasmine.PrettyPrinter: format() nested too deeply!'); + } + + this.ppNestLevel_++; + try { + if (value === jasmine.undefined) { + this.emitScalar('undefined'); + } else if (value === null) { + this.emitScalar('null'); + } else if (value === jasmine.getGlobal()) { + this.emitScalar('<global>'); + } else if (value instanceof jasmine.Matchers.Any) { + this.emitScalar(value.toString()); + } 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('<circular reference: ' + (jasmine.isArray_(value) ? 'Array' : 'Object') + '>'); + } 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 (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) { + 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) { + 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('<getter>'); + } else { + self.format(obj[property]); + } + }); + + this.append(' }'); +}; + +jasmine.StringPrettyPrinter.prototype.append = function(value) { + this.string += value; +}; +jasmine.Queue = function(env) { + this.env = env; + this.blocks = []; + this.running = false; + this.index = 0; + this.offset = 0; + this.abort = false; +}; + +jasmine.Queue.prototype.addBefore = function(block) { + this.blocks.unshift(block); +}; + +jasmine.Queue.prototype.add = function(block) { + this.blocks.push(block); +}; + +jasmine.Queue.prototype.insertNext = function(block) { + 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) { + 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 <code>jasmine.log</code> 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)); + } 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)); + } + 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)); + } + } + for (i = 0; i < runner.after_.length; i++) { + this.queue.add(new jasmine.Block(this.env, runner.after_[i], this)); + } +}; + +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); + } +}; +// 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); + } +}; + +jasmine.version_= { + "major": 1, + "minor": 1, + "build": 0, + "revision": 1308618948, + "release_candidate": 1 +}; diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine_favicon.png b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine_favicon.png Binary files differnew file mode 100644 index 0000000000..218f3b4371 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/jasmine_favicon.png diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/json2.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/json2.js new file mode 100644 index 0000000000..ac5807921f --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/lib/json2.js @@ -0,0 +1,478 @@ +/* + 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'); + }; + } +}()); diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-array.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-array.js new file mode 100644 index 0000000000..6c353d85b7 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-array.js @@ -0,0 +1,1070 @@ +describe('Array', function() { + var testSubject; + beforeEach(function() { + testSubject = [2, 3, undefined, true, 'hej', null, false, 0]; + delete testSubject[1]; + }); + 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() { + "use strict"; + var expected, actual; + + beforeEach(function() { + expected = {0:2, 2: undefined, 3:true, 4: 'hej', 5:null, 6:false, 7:0 }; + actual = {}; + }); + it('should pass the right parameters', function() { + var callback = jasmine.createSpy('callback'), + 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], + i = 0; + arr.forEach(function(a) { + i++; + 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), + o = { a: actual }; + + Array.prototype.forEach.call(ts, function(obj, index) { + this.a[index] = obj; + }, o); + expect(actual).toExactlyMatch(expected); + }); + }); + describe('some', function() { + var actual, expected, numberOfRuns; + + beforeEach(function() { + expected = {0:2, 2: undefined, 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], + i = 0; + arr.some(function(a) { + i++; + 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; + if(numberOfRuns == 3) { + return true; + } + return false; + }); + 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; + if(numberOfRuns == 3) { + return true; + } + return false; + }, 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; + if(numberOfRuns == 3) { + return true; + } + return false; + }); + 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; + if(numberOfRuns == 3) { + return true; + } + return false; + }, o); + expect(actual).toExactlyMatch(expected); + }); + }); + describe('every', function() { + var actual, expected, numberOfRuns; + + beforeEach(function() { + expected = {0:2, 2: undefined, 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], + i = 0; + arr.every(function(a) { + i++; + 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; + if(numberOfRuns == 3) { + return false; + } + return true; + }); + 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; + if(numberOfRuns == 3) { + return false; + } + return true; + }, 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; + if(numberOfRuns == 3) { + return false; + } + return true; + }); + 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; + if(numberOfRuns == 3) { + return false; + } + return true; + }, o); + expect(actual).toExactlyMatch(expected); + }); + }); + + describe('indexOf', function() { + "use strict"; + var actual, expected, testSubject; + + beforeEach(function() { + testSubject = [2, 3, undefined, true, 'hej', null, 2, false, 0]; + delete testSubject[1]; + + }); + + it('should find the element', function() { + expected = 4; + actual = testSubject.indexOf('hej'); + expect(actual).toEqual(expected); + }); + it('should not find the element', function() { + expected = -1; + actual = testSubject.indexOf('mus'); + expect(actual).toEqual(expected); + }); + it('should find undefined as well', function() { + expected = -1; + actual = testSubject.indexOf(undefined); + expect(actual).not.toEqual(expected); + }); + it('should skip unset indexes', function() { + expected = 2; + actual = testSubject.indexOf(undefined); + expect(actual).toEqual(expected); + }); + it('should use a strict test', function() { + actual = testSubject.indexOf(null); + expect(actual).toEqual(5); + + actual = testSubject.indexOf('2'); + expect(actual).toEqual(-1); + }); + it('should skip the first if fromIndex is set', function() { + expect(testSubject.indexOf(2, 2)).toEqual(6); + expect(testSubject.indexOf(2, 0)).toEqual(0); + expect(testSubject.indexOf(2, 6)).toEqual(6); + }); + it('should work with negative fromIndex', function() { + expect(testSubject.indexOf(2, -3)).toEqual(6); + expect(testSubject.indexOf(2, -9)).toEqual(0); + }); + it('should work with fromIndex being greater than the length', function() { + expect(testSubject.indexOf('hej', 20)).toEqual(-1); + }); + it('should work with fromIndex being negative and greater than the length', function() { + expect(testSubject.indexOf('hej', -20)).toEqual(4); + }); + + describe('Array-like', function ArrayLike() { + var indexOf = Array.prototype.indexOf, + testAL; + beforeEach(function beforeEach() { + testAL = {}; + testSubject = [2, 3, undefined, 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).toEqual(expected); + }); + it('should not find the element (array-like)', function() { + expected = -1; + actual = indexOf.call(testAL, 'mus'); + expect(actual).toEqual(expected); + }); + it('should find undefined as well (array-like)', function() { + expected = -1; + actual = indexOf.call(testAL, undefined); + expect(actual).not.toEqual(expected); + }); + it('should skip unset indexes (array-like)', function() { + expected = 2; + actual = indexOf.call(testAL, undefined); + expect(actual).toEqual(expected); + }); + it('should use a strict test (array-like)', function() { + actual = Array.prototype.indexOf.call(testAL, null); + expect(actual).toEqual(5); + + actual = Array.prototype.indexOf.call(testAL, '2'); + expect(actual).toEqual(-1); + }); + it('should skip the first if fromIndex is set (array-like)', function() { + expect(indexOf.call(testAL, 2, 2)).toEqual(6); + expect(indexOf.call(testAL, 2, 0)).toEqual(0); + expect(indexOf.call(testAL, 2, 6)).toEqual(6); + }); + it('should work with negative fromIndex (array-like)', function() { + expect(indexOf.call(testAL, 2, -3)).toEqual(6); + expect(indexOf.call(testAL, 2, -9)).toEqual(0); + }); + it('should work with fromIndex being greater than the length (array-like)', function() { + expect(indexOf.call(testAL, 'hej', 20)).toEqual(-1); + }); + it('should work with fromIndex being negative and greater than the length (array-like)', function() { + expect(indexOf.call(testAL, 'hej', -20)).toEqual(4); + }); + }); + }); + describe('lastIndexOf', function() { + "use strict"; + var actual, expected, testSubject, testAL; + + beforeEach(function() { + testSubject = [2, 3, undefined, 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).toEqual(expected); + }); + it('should not find the element', function() { + expected = -1; + actual = testSubject.lastIndexOf('mus'); + expect(actual).toEqual(expected); + }); + it('should find undefined as well', function() { + expected = -1; + actual = testSubject.lastIndexOf(undefined); + expect(actual).not.toEqual(expected); + }); + it('should skip unset indexes', function() { + expected = 2; + actual = testSubject.lastIndexOf(undefined); + expect(actual).toEqual(expected); + }); + it('should use a strict test', function() { + actual = testSubject.lastIndexOf(null); + expect(actual).toEqual(5); + + actual = testSubject.lastIndexOf('2'); + expect(actual).toEqual(-1); + }); + it('should skip the first if fromIndex is set', function() { + expect(testSubject.lastIndexOf(2, 2)).toEqual(0); + expect(testSubject.lastIndexOf(2, 0)).toEqual(0); + expect(testSubject.lastIndexOf(2, 6)).toEqual(6); + }); + it('should work with negative fromIndex', function() { + expect(testSubject.lastIndexOf(2, -3)).toEqual(6); + expect(testSubject.lastIndexOf(2, -9)).toEqual(0); + }); + it('should work with fromIndex being greater than the length', function() { + expect(testSubject.lastIndexOf(2, 20)).toEqual(6); + }); + it('should work with fromIndex being negative and greater than the length', function() { + expect(testSubject.lastIndexOf(2, -20)).toEqual(-1); + }); + }); + + describe('Array like', function() { + var lastIndexOf = Array.prototype.lastIndexOf, + 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).toEqual(expected); + }); + it('should not find the element (array-like)', function() { + expected = -1; + actual = lastIndexOf.call(testAL, 'mus'); + expect(actual).toEqual(expected); + }); + it('should find undefined as well (array-like)', function() { + expected = -1; + actual = lastIndexOf.call(testAL, undefined); + expect(actual).not.toEqual(expected); + }); + it('should skip unset indexes (array-like)', function() { + expected = 2; + actual = lastIndexOf.call(testAL, undefined); + expect(actual).toEqual(expected); + }); + it('should use a strict test (array-like)', function() { + actual = lastIndexOf.call(testAL, null); + expect(actual).toEqual(5); + + actual = lastIndexOf.call(testAL, '2'); + expect(actual).toEqual(-1); + }); + it('should skip the first if fromIndex is set', function() { + expect(lastIndexOf.call(testAL, 2, 2)).toEqual(0); + expect(lastIndexOf.call(testAL, 2, 0)).toEqual(0); + expect(lastIndexOf.call(testAL, 2, 6)).toEqual(6); + }); + it('should work with negative fromIndex', function() { + expect(lastIndexOf.call(testAL, 2, -3)).toEqual(6); + expect(lastIndexOf.call(testAL, 2, -9)).toEqual(0); + }); + it('should work with fromIndex being greater than the length', function() { + expect(lastIndexOf.call(testAL, 2, 20)).toEqual(6); + }); + it('should work with fromIndex being negative and greater than the length', function() { + expect(lastIndexOf.call(testAL, 2, -20)).toEqual(-1); + }); + }); + }); + + describe('filter', function() { + var filteredArray, + callback = function callback(o, i, arr) { + return ( + i != 3 && i != 5 + ); + }; + + beforeEach(function() { + testSubject = [2, 3, undefined, true, 'hej', 3, null, false, 0]; + delete testSubject[1]; + filteredArray = [2, undefined, 'hej', null, false, 0]; + }); + describe('Array object', function() { + + it('should call the callback with the proper arguments', function() { + var callback = jasmine.createSpy('callback'), + arr = ['1']; + arr.filter(callback); + expect(callback).toHaveBeenCalledWith('1', 0, arr); + }); + it('should not affect elements added to the array after it has begun', function() { + var arr = [1,2,3], + i = 0; + arr.filter(function(a) { + i++; + if(i <= 4) { + arr.push(a+3); + } + return true; + }); + expect(arr).toEqual([1,2,3,4,5,6]); + expect(i).toBe(3); + }); + it('should skip non-set 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 callback with the proper arguments', function() { + var callback = jasmine.createSpy('callback'), + arr = createArrayLikeFromArray(['1']); + Array.prototype.filter.call(arr, callback); + expect(callback).toHaveBeenCalledWith('1', 0, arr); + }); + it('should not affect elements added to the array after it has begun', function() { + var arr = createArrayLikeFromArray([1,2,3]), + i = 0; + Array.prototype.filter.call(arr, function(a) { + i++; + if(i <= 4) { + arr[i+2] = a+3; + } + return true; + }); + delete arr.length; + expect(arr).toExactlyMatch([1,2,3,4,5,6]); + expect(i).toBe(3); + }); + it('should skip non-set values', function() { + var passedValues = {}; + testSubject = createArrayLikeFromArray([1,2,3,4]); + delete testSubject[1]; + Array.prototype.filter.call(testSubject, function(o, i) { + passedValues[i] = o; + return true; + }); + delete testSubject.length; + expect(passedValues).toExactlyMatch(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; + return true; + }, passedValues); + delete testSubject.length; + expect(passedValues).toExactlyMatch(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); + }); + }); + }); + describe('map', function() { + var callback; + beforeEach(function() { + var i = 0; + callback = function() { + return i++; + }; + }); + describe('Array object', function() { + it('should call callback with the right parameters', function() { + var callback = jasmine.createSpy('callback'), + array = [1]; + array.map(callback); + expect(callback).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], + i = 0; + arr.map(function(o) { + arr.push(o+3); + i++; + 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), + 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], + i = 0; + delete array[2]; + array.map(function() { + i++; + }); + expect(i).toBe(3); + }); + }); + describe('Array-like', function() { + beforeEach(function() { + testSubject = createArrayLikeFromArray(testSubject); + }); + it('should call callback with the right parameters', function() { + var callback = jasmine.createSpy('callback'), + array = createArrayLikeFromArray([1]); + Array.prototype.map.call(array, callback); + expect(callback).toHaveBeenCalledWith(1, 0, array); + }); + it('should set the context correctly', function() { + var context = {}; + Array.prototype.map.call(testSubject, function(o,i) { + this[i] = o; + }, context); + delete testSubject.length; + expect(context).toExactlyMatch(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]), + i = 0; + Array.prototype.map.call(arr, function(o) { + Array.prototype.push.call(arr, o+3); + i++; + return o; + }); + delete arr.length; + 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 = Array.prototype.map.call(testSubject, callback), + 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]), + i = 0; + delete array[2]; + Array.prototype.map.call(array, function() { + i++; + }); + expect(i).toBe(3); + }); + }); + }); + + 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], + i = 0; + arr.reduce(function(a, b) { + i++; + 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 (a||'').toString()+(b||'').toString(); + })).toEqual(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]), + i = 0; + Array.prototype.reduce.call(arr, function(a, b) { + i++; + 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 (a||'').toString()+(b||'').toString(); + })).toEqual('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); + }); + }); + }); + 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], + i = 0; + arr.reduceRight(function(a, b) { + i++; + 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 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 (a||'').toString()+(b||'').toString(); + })).toEqual('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]), + i = 0; + Array.prototype.reduceRight.call(arr, function(a, b) { + i++; + 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 (a||'').toString()+(b||'').toString(); + })).toEqual('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); + }); + }); + }); + + describe('isArray', function () { + it('should work for Array', function () { + var ret = Array.isArray([]); + + expect(ret).toBe(true); + }); + + it('should fail for other objects', function () { + var objects = [ + "someString", + true, + false, + 42, + 0, + {}, + Object.create(null), + /foo/, + arguments, + document.getElementsByTagName("div") + ]; + + objects.forEach(function (v) { + expect(Array.isArray(v)).toBe(false); + }); + }); + }); + + +}); diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-date.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-date.js new file mode 100644 index 0000000000..26ab28529e --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-date.js @@ -0,0 +1,40 @@ +describe('Date', function () { + + describe('now', function () { + it('should be the current time', function () { + expect(Date.now() === new Date().getTime()).toBe(true); + }); + }); + + describe("parse", function () { + // TODO: Write the rest of the test. + + it('should support extended years', function () { + + expect(Date.parse('0001-01-01T00:00:00Z')).toBe(-62135596800000); + expect(Date.parse('+275760-09-13T00:00:00.000Z')).toBe(8.64e15); + expect(Date.parse('+033658-09-27T01:46:40.000Z')).toBe(1e15); + expect(Date.parse('-000001-01-01T00:00:00Z')).toBe(-62198755200000); + expect(Date.parse('+002009-12-15T00:00:00Z')).toBe(1260835200000); + + }); + + }); + + 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); + }); + }); + + describe("toJSON", function () { + it('should return the isoString when stringified', function () { + var date = new Date(); + expect(JSON.stringify(date.toISOString())).toBe(JSON.stringify(date)); + }) + }); + +});
\ No newline at end of file diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-function.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-function.js new file mode 100644 index 0000000000..adb6023fc2 --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-function.js @@ -0,0 +1,137 @@ + +describe('Function', function() { + "use strict"; + describe('bind', function() { + var actual, expected, + testSubject; + + testSubject = { + push: function(o) { + this.a.push(o); + } + }; + + 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('passes the correct arguments as a constructor', function() { + var ret, expected = { name: "Correct" }; + testSubject.func = function(arg) { + return arg; + }.bind({ name: "Incorrect" }); + 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 () { + return oracle; + }.bind(null); + var result = new subject; + expect(result).toBe(oracle); + }); + it('returns the correct value if constructor returns primitive', function() { + var oracle = [1, 2, 3]; + var subject = function () { + return oracle; + }.bind(null); + var result = new subject; + expect(result).toBe(oracle); + + oracle = {}; + result = new subject; + expect(result).toBe(oracle); + + oracle = function(){}; + result = new subject; + expect(result).toBe(oracle); + + oracle = "asdf"; + result = new subject; + expect(result).not.toBe(oracle); + + oracle = null; + result = new subject; + expect(result).not.toBe(oracle); + + oracle = true; + result = new subject; + expect(result).not.toBe(oracle); + + oracle = 1; + result = new subject; + expect(result).not.toBe(oracle); + }); + }); +}); diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-object.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-object.js new file mode 100644 index 0000000000..8f2a87ad8f --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-object.js @@ -0,0 +1,84 @@ +describe('Object', function () { + "use strict"; + + describe("Object.keys", function () { + var obj = { + "str": "boz", + "obj": { }, + "arr": [], + "bool": true, + "num": 42, + "null": null, + "undefined": undefined + }; + + var loopedValues = []; + for (var k in obj) { + loopedValues.push(k); + } + + var keys = Object.keys(obj); + it('should have correct length', function () { + expect(keys.length).toBe(7); + }); + + 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); + }) + }); + + it('should throw error for non object', function () { + var e = {}; + expect(function () { + try { + Object.keys(42) + } catch (err) { + throw e; + } + }).toThrow(e); + }); + }); + + describe("Object.isExtensible", function () { + var obj = { }; + + it('should return true if object is extensible', function () { + expect(Object.isExtensible(obj)).toBe(true); + }); + + it('should return false if object is not extensible', function () { + expect(Object.isExtensible(Object.preventExtensions(obj))).toBe(false); + }); + + it('should return false if object is seal', function () { + expect(Object.isExtensible(Object.seal(obj))).toBe(false); + }); + + it('should return false if object is freeze', function () { + expect(Object.isExtensible(Object.freeze(obj))).toBe(false); + }); + + it('should throw error for non object', function () { + var e1 = {}; + expect(function () { + try { + Object.isExtensible(42) + } catch (err) { + throw e1; + } + }).toThrow(e1); + }); + }); + +});
\ No newline at end of file diff --git a/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-string.js b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-string.js new file mode 100644 index 0000000000..c31498dd8a --- /dev/null +++ b/third_party/webkit/PerformanceTests/Speedometer/resources/flightjs-example-app/components/es5-shim/tests/spec/s-string.js @@ -0,0 +1,11 @@ +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()).toEqual("Hello, World!"); + expect(test.trim().length).toEqual(13); + }); + }); +}); |