├── .eslintrc
├── .github
└── workflows
│ ├── node-aught.yml
│ ├── node-pretest.yml
│ ├── node-tens.yml
│ ├── rebase.yml
│ └── require-allow-edits.yml
├── .gitignore
├── .npmignore
├── .npmrc
├── .nycrc
├── .travis.yml
├── CHANGELOG.md
├── Gruntfile.js
├── LICENSE
├── README.md
├── bower.json
├── component.json
├── es6-sham.js
├── es6-sham.map
├── es6-sham.min.js
├── es6-shim.js
├── es6-shim.map
├── es6-shim.min.js
├── node_modules
├── chai
│ └── chai.js
├── es5-shim
│ └── es5-shim.js
├── mocha
│ ├── mocha.css
│ └── mocha.js
└── promises-es6-tests
│ └── bundle
│ └── promises-es6-tests.js
├── package.json
├── test-sham
├── function.js
├── index.html
└── set-prototype-of.js
├── test
├── array.js
├── browser-onload.js
├── browser-setup.js
├── date.js
├── google-translate.html
├── index.html
├── json.js
├── map.js
├── math.js
├── mocha.opts
├── native.html
├── number.js
├── object.js
├── promise.js
├── promise
│ ├── all.js
│ ├── evil-promises.js
│ ├── promises-aplus.js
│ ├── promises-es6.js
│ ├── race.js
│ ├── reject.js
│ ├── resolve.js
│ ├── simple.js
│ └── subclass.js
├── reflect.js
├── regexp.js
├── set.js
├── string.js
├── test_helpers.js
├── worker-runner.workerjs
└── worker-test.js
└── testling.html
/.eslintrc:
--------------------------------------------------------------------------------
1 | {
2 | "root": true,
3 |
4 | "extends": "@ljharb",
5 |
6 | "ignorePatterns": [
7 | "Gruntfile.js",
8 | "*.min.js",
9 | ],
10 |
11 | "rules": {
12 | "array-bracket-newline": [0],
13 | "array-element-newline": [0],
14 | "callback-return": [0],
15 | "complexity": [1],
16 | "consistent-return": [1],
17 | "eqeqeq": [2, "allow-null"],
18 | "func-name-matching": [0],
19 | "global-require": [0],
20 | "id-length": [2, { "min": 1, "max": 40 }],
21 | "indent": [2, 2],
22 | "max-depth": [2, 5],
23 | "max-len": 0,
24 | "max-lines": [1],
25 | "max-lines-per-function": [0],
26 | "max-params": [2, 4],
27 | "max-statements": [1, 25],
28 | "max-statements-per-line": [2, { "max": 2 }],
29 | "multiline-comment-style": [0],
30 | "new-cap": [2, { "capIsNewExceptions": ["Call", "Construct", "CreateHTML", "GetIterator", "GetMethod", "IsCallable", "IsConstructor", "IsPromise", "IsRegExp", "IteratorClose", "IteratorComplete", "IteratorNext", "IteratorStep", "Map", "OrigNumber", "RequireObjectCoercible", "SameValue", "SameValueZero", "Set", "SpeciesConstructor", "ToInteger", "ToLength", "ToNumber", "ToObject", "ToString", "ToUint32", "TypeIsObject"] }],
31 | "no-constant-condition": [1],
32 | "no-extend-native": [2, { "exceptions": ["Set"] }],
33 | "no-extra-parens": 0,
34 | "no-implicit-coercion": [2, {
35 | "boolean": false,
36 | "number": false,
37 | "string": true
38 | }],
39 | "no-invalid-this": [0],
40 | "no-loss-of-precision": [1],
41 | "no-native-reassign": [2, { "exceptions": ["Number", "Promise", "RegExp"] }],
42 | "no-negated-condition": [1],
43 | "no-param-reassign": [1],
44 | "no-plusplus": [1],
45 | "no-restricted-syntax": [2, "DebuggerStatement", "LabeledStatement", "WithStatement"],
46 | "no-shadow": [1],
47 | "no-underscore-dangle": [0],
48 | "no-unused-vars": [1, { "vars": "all", "args": "after-used" }],
49 | "no-use-before-define": [1],
50 | "no-useless-call": [0],
51 | "object-curly-newline": [1],
52 | "sort-keys": [0],
53 | "spaced-comment": [0],
54 | "strict": [0]
55 | },
56 | "overrides": [
57 | {
58 | "files": "test/**",
59 | "env": {
60 | "browser": true,
61 | "mocha": true,
62 | },
63 | "globals": {
64 | "assert": false,
65 | "expect": false,
66 | "chai": false,
67 | },
68 | "rules": {
69 | "array-callback-return": 0,
70 | "func-name-matching": 0,
71 | "max-lines-per-function": 0,
72 | "max-statements-per-line": [2, { "max": 2 }],
73 | "no-restricted-properties": 1,
74 | "symbol-description": 0,
75 | "prefer-promise-reject-errors": 0,
76 | "consistent-return": 0,
77 | },
78 | },
79 | {
80 | "files": "test-sham/**",
81 | "env": {
82 | "mocha": true,
83 | },
84 | "globals": {
85 | "expect": false,
86 | },
87 | "rules": {
88 | "max-nested-callbacks": [2, 5],
89 | },
90 | }
91 | ]
92 | }
93 |
--------------------------------------------------------------------------------
/.github/workflows/node-aught.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: node.js < 10'
2 |
3 | on: [pull_request, push]
4 |
5 | jobs:
6 | tests:
7 | uses: ljharb/actions/.github/workflows/node.yml@main
8 | with:
9 | range: '< 10'
10 | type: minors
11 | command: npm run tests-only
12 |
13 | node:
14 | name: 'node < 10'
15 | needs: [tests]
16 | runs-on: ubuntu-latest
17 | steps:
18 | - run: 'echo tests completed'
19 |
--------------------------------------------------------------------------------
/.github/workflows/node-pretest.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: pretest/posttest'
2 |
3 | on: [pull_request, push]
4 |
5 | jobs:
6 | tests:
7 | uses: ljharb/actions/.github/workflows/pretest.yml@main
8 |
--------------------------------------------------------------------------------
/.github/workflows/node-tens.yml:
--------------------------------------------------------------------------------
1 | name: 'Tests: node.js >= 10'
2 |
3 | on: [pull_request, push]
4 |
5 | jobs:
6 | tests:
7 | uses: ljharb/actions/.github/workflows/node.yml@main
8 | with:
9 | range: '>= 10'
10 | type: minors
11 | command: NODE_OPTIONS=--unhandled-rejections=none node -pe '' 2>/dev/null && NODE_OPTIONS=--unhandled-rejections=none npm run tests-only || npm run tests-only
12 |
13 | node:
14 | name: 'node >= 10'
15 | needs: [tests]
16 | runs-on: ubuntu-latest
17 | steps:
18 | - run: 'echo tests completed'
19 |
--------------------------------------------------------------------------------
/.github/workflows/rebase.yml:
--------------------------------------------------------------------------------
1 | name: Automatic Rebase
2 |
3 | on: [pull_request_target]
4 |
5 | jobs:
6 | _:
7 | name: "Automatic Rebase"
8 |
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - uses: actions/checkout@v2
13 | - uses: ljharb/rebase@master
14 | env:
15 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
16 |
--------------------------------------------------------------------------------
/.github/workflows/require-allow-edits.yml:
--------------------------------------------------------------------------------
1 | name: Require “Allow Edits”
2 |
3 | on: [pull_request_target]
4 |
5 | jobs:
6 | _:
7 | name: "Require “Allow Edits”"
8 |
9 | runs-on: ubuntu-latest
10 |
11 | steps:
12 | - uses: ljharb/require-allow-edits@main
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # gitignore
2 |
3 | .DS_Store
4 | node_modules/
5 |
6 | # Only apps should have lockfiles
7 | npm-shrinkwrap.json
8 | package-lock.json
9 | yarn.lock
10 |
11 | coverage/
12 | .nyc_output/
13 |
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | node_modules/
3 | .travis.yml
4 | testling.html
5 |
--------------------------------------------------------------------------------
/.npmrc:
--------------------------------------------------------------------------------
1 | package-lock=false
2 |
--------------------------------------------------------------------------------
/.nycrc:
--------------------------------------------------------------------------------
1 | {
2 | "all": true,
3 | "check-coverage": false,
4 | "reporter": ["text-summary", "text", "html", "json"],
5 | "exclude": [
6 | "Gruntfile.js",
7 | "*.min.js",
8 | "coverage",
9 | "test",
10 | "test-sham"
11 | ]
12 | }
13 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | os:
3 | - linux
4 | before_install:
5 | - 'if [ -n "${SAUCE-}" ]; then npm install -g grunt-cli; fi'
6 | script:
7 | - 'if [ -n "${SAUCE-}" ]; then npm run sauce; fi'
8 | # NOTE: sauce_connect is disabled, because it applies to every test and we only need it on one of them.
9 | # It's available inside `npm run sauce`
10 | # addons:
11 | # sauce_connect: true
12 | matrix:
13 | fast_finish: true
14 | include:
15 | - node_js: "lts/*"
16 | env: SAUCE=true
17 | allow_failures:
18 | - env: SAUCE=true
19 | env:
20 | global:
21 | - secure: YD4HLTE93NhSxa+64MYHhnbJ2ZkREp/HGiFGE4q+AWShqAiehtqE/K3hQUe7p0+1/2/34avhm2bz31j508ayCobm6SSUhpleJH58IK3v4LI2o9qtM+2N/MPJFOIvbziHqOM6fPluowU0k3OSdEAp4U+6S23wKSuXzcUSK8upAiM=
22 | - secure: k7+PgLcGJL1zyMMxZ8DSRxRrmLr5sb9i4M1kCdUvw2kRGacqoI3UhdvO2AyrAD0TAjIQoRM4dL37WsgJijhTNOu1gTb5lMUXWSQU47T7tFTvpM6OlGvQ54I7iAgv5NABZ/0gDGlQDrVdb9hQPLG1FDrMxsxcdXfgXqzqbhNsv7I=
23 | - SAUCE_HAS_TUNNEL=true
24 |
--------------------------------------------------------------------------------
/Gruntfile.js:
--------------------------------------------------------------------------------
1 | 'use strict';
2 |
3 | module.exports = function (grunt) {
4 | var browsers = [
5 | { browserName: 'firefox', version: '19', platform: 'XP' },
6 | { browserName: 'firefox', platform: 'linux' },
7 | { browserName: 'firefox', platform: 'OS X 10.10' },
8 | { browserName: 'chrome', platform: 'linux' },
9 | { browserName: 'chrome', platform: 'OS X 10.9' },
10 | { browserName: 'chrome', platform: 'XP' },
11 | { browserName: 'internet explorer', platform: 'Windows 8.1', version: '11' },
12 | { browserName: 'internet explorer', platform: 'WIN8', version: '10' },
13 | { browserName: 'internet explorer', platform: 'VISTA', version: '9' },
14 | { browserName: 'safari', platform: 'OS X 10.6' },
15 | { browserName: 'safari', platform: 'OS X 10.8' },
16 | { browserName: 'safari', platform: 'OS X 10.9' },
17 | { browserName: 'safari', platform: 'OS X 10.10' },
18 | { browserName: 'iphone', platform: 'OS X 10.9', version: '7.1' },
19 | { browserName: 'android', platform: 'Linux', version: '4.4' },
20 | ];
21 | var extraBrowsers = [
22 | { browserName: 'firefox', platform: 'linux', version: '30' },
23 | { browserName: 'firefox', platform: 'linux', version: '25' },
24 | { browserName: 'iphone', platform: 'OS X 10.8', version: '6.1' },
25 | { browserName: 'iphone', platform: 'OS X 10.8', version: '5.1' },
26 | { browserName: 'android', platform: 'Linux', version: '4.2' },
27 | // XXX haven't investigated these:
28 | // { browserName: 'opera', platform: 'Windows 7', version: '12' },
29 | // { browserName: 'opera', platform: 'Windows 2008', version: '12' }
30 | // { browserName: 'iphone', platform: 'OS X 10.6', version: '4.3' },
31 | // { browserName: 'android', platform: 'Linux', version: '4.0' },
32 | ];
33 | if (grunt.option('extra')) {
34 | browsers = browsers.concat(extraBrowsers);
35 | }
36 | grunt.initConfig({
37 | connect: {
38 | server: {
39 | options: {
40 | base: '',
41 | port: 9999,
42 | useAvailablePort: true
43 | }
44 | }
45 | },
46 | 'saucelabs-mocha': {
47 | all: {
48 | options: {
49 | urls: (function () {
50 | var urls = ['http://localhost:9999/test/'];
51 | if (grunt.option('extra')) {
52 | urls.push('http://localhost:9999/test-sham/');
53 | }
54 | return urls;
55 | }()),
56 | // tunnelTimeout: 5,
57 | build: process.env.TRAVIS_BUILD_NUMBER,
58 | tunneled: !process.env.SAUCE_HAS_TUNNEL,
59 | identifier: process.env.TRAVIS_JOB_NUMBER,
60 | sauceConfig: {
61 | 'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER
62 | },
63 | // concurrency: 3,
64 | browsers: browsers,
65 | testname: (function () {
66 | var testname = 'mocha';
67 | if (process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false') {
68 | testname += ' (PR ' + process.env.TRAVIS_PULL_REQUEST + ')';
69 | }
70 | if (process.env.TRAVIS_BRANCH && process.env.TRAVIS_BRANCH !== 'false') {
71 | testname += ' (branch ' + process.env.TRAVIS_BRANCH + ')';
72 | }
73 | return testname;
74 | }()),
75 | tags: (function () {
76 | var tags = [];
77 | if (process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false') {
78 | tags.push('PR-' + process.env.TRAVIS_PULL_REQUEST);
79 | }
80 | if (process.env.TRAVIS_BRANCH && process.env.TRAVIS_BRANCH !== 'false') {
81 | tags.push(process.env.TRAVIS_BRANCH);
82 | }
83 | return tags;
84 | }())
85 | }
86 | }
87 | },
88 | watch: {}
89 | });
90 | // Loading dependencies
91 | for (var key in grunt.file.readJSON('package.json').devDependencies) {
92 | if (key !== 'grunt' && key.indexOf('grunt') === 0) {
93 | grunt.loadNpmTasks(key);
94 | }
95 | }
96 | grunt.registerTask('dev', ['connect', 'watch']);
97 | grunt.registerTask('sauce', ['connect', 'saucelabs-mocha']);
98 | };
99 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2019 Paul Miller (https://paulmillr.com)
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ES6 Shim [![Version Badge][npm-version-svg]][package-url]
2 | Provides compatibility shims so that legacy JavaScript engines behave as
3 | closely as possible to ECMAScript 6 (Harmony).
4 |
5 | [![github actions][actions-image]][actions-url]
6 | [![coverage][codecov-image]][codecov-url]
7 | [![License][license-image]][license-url]
8 | [![Downloads][downloads-image]][downloads-url]
9 |
10 | [![npm badge][npm-badge-png]][package-url]
11 |
12 |
13 |
14 |
15 |
16 | [HTML version of the final ECMAScript 6 spec][spec-html-url]
17 |
18 | ## Installation
19 | If you want to use it in browser:
20 |
21 | * Just include `es6-shim` before your scripts.
22 | * Include [es5-shim][es5-shim-url] especially if your browser doesn't support ECMAScript 5 - but every JS engine requires the `es5-shim` to correct broken implementations, so it's strongly recommended to always include it. Additionally, `es5-shim` should be loaded before `es6-shim`.
23 |
24 | For `node.js`, `io.js`, or any `npm`-managed workflow (this is the recommended method):
25 |
26 | npm install es6-shim
27 |
28 | Alternative methods:
29 | * `component install paulmillr/es6-shim` if you’re using [component(1)](https://github.com/componentjs/component).
30 | * `bower install es6-shim` if you’re using [Bower](http://bower.io/).
31 |
32 | In both browser and node you may also want to include `unorm`; see the [`String.prototype.normalize`](#stringprototypenormalize) section for details.
33 |
34 | ## Safe shims
35 |
36 | * `Map` (requires ES5 property descriptor support) ([a standalone shim is also available](https://npmjs.com/es-map))
37 | * `Set` (requires ES5 property descriptor support) ([a standalone shim is also available](https://npmjs.com/es-set))
38 | * `Promise`
39 | * `String`:
40 | * `fromCodePoint()` ([a standalone shim is also available](https://npmjs.com/string.fromcodepoint))
41 | * `raw()` ([a stanadlone shim is also available](https://www.npmjs.com/package/string.raw))
42 | * `String.prototype`:
43 | * `codePointAt()` ([a standalone shim is also available](https://npmjs.com/string.prototype.codepointat))
44 | * `endsWith()` ([a standalone shim is also available](https://npmjs.com/string.prototype.endswith))
45 | * `includes()` ([a standalone shim is also available](https://npmjs.com/string.prototype.includes))
46 | * `repeat()` ([a standalone shim is also available](https://npmjs.com/string.prototype.repeat))
47 | * `startsWith()` ([a standalone shim is also available](https://npmjs.com/string.prototype.startswith))
48 | * `RegExp`:
49 | * `new RegExp`, when given a RegExp as the pattern, will no longer throw when given a "flags" string argument. (requires ES5)
50 | * `RegExp.prototype`:
51 | * `flags` (requires ES5) ([a standalone shim is also available](https://npmjs.com/regexp.prototype.flags))
52 | * `[Symbol.match]` (requires native `Symbol`s)
53 | * `[Symbol.replace]` (requires native `Symbol`s)
54 | * `[Symbol.search]` (requires native `Symbol`s)
55 | * `[Symbol.split]` (requires native `Symbol`s)
56 | * `toString`
57 | * `Number`:
58 | * binary and octal literals: `Number('0b1')` and `Number('0o7')`
59 | * `EPSILON` ([a standalone shim is also available](https://www.npmjs.com/package/es-constants))
60 | * `MAX_SAFE_INTEGER` ([a standalone shim is also available](https://www.npmjs.com/package/es-constants))
61 | * `MIN_SAFE_INTEGER` ([a standalone shim is also available](https://www.npmjs.com/package/es-constants))
62 | * `isNaN()` ([a standalone shim is also available](https://www.npmjs.com/package/is-nan))
63 | * `isInteger()` ([a standalone shim is also available](https://www.npmjs.com/package/number.isinteger))
64 | * `isSafeInteger()`([a standalone shim is also available](https://www.npmjs.com/package/number.issafeinteger))
65 | * `isFinite()` ([a standalone shim is also available](https://www.npmjs.com/package/number.isfinite))
66 | * `parseInt()` ([a standalone shim is also available](https://www.npmjs.com/package/parseint))
67 | * `parseFloat()`
68 | * `Array`:
69 | * `from()` ([a standalone shim is also available](https://www.npmjs.com/package/array.from))
70 | * `of()` ([a standalone shim is also available](https://www.npmjs.com/package/array.of))
71 | * `Array.prototype`:
72 | * `copyWithin()` ([a standalone shim is also available](https://npmjs.com/array.prototype.copywithin))
73 | * `entries()` ([a standalone shim is also available](https://npmjs.com/array.prototype.entries))
74 | * `fill()`
75 | * `find()` ([a standalone shim is also available](https://npmjs.com/array.prototype.find))
76 | * `findIndex()` ([a standalone shim is also available](https://npmjs.com/array.prototype.findindex))
77 | * `keys()` ([a standalone shim is also available](https://npmjs.com/array.prototype.keys))
78 | * `values()` ([a standalone shim is also available](https://npmjs.com/array.prototype.values))
79 | * `indexOf()` (ES6 errata) ([a standalone shim is also available](https://npmjs.com/array.prototype.indexof))
80 | * `Object`:
81 | * `assign()` ([a standalone shim is also available](https://npmjs.com/object.assign))
82 | * `is()` ([a standalone shim is also available](https://npmjs.com/object-is))
83 | * `keys()` (in ES5, but no longer throws on non-object non-null/undefined values in ES6) ([a standalone shim is also available](https://npmjs.com/object-keys)
84 | * `setPrototypeOf()` (IE >= 11)
85 | * `Function.prototype`:
86 | * `name` (es6-sham, covers IE 9-11) ([a standalone shim is also available](https://npmjs.com/function.prototype.name)
87 | * `Math`:
88 | * `acosh()` ([a standalone shim is also available](https://npmjs.com/math.acosh))
89 | * `asinh()`
90 | * `atanh()` ([a standalone shim is also available](https://npmjs.com/math.atanh))
91 | * `cbrt()` ([a standalone shim is also available](https://npmjs.com/math.cbrt))
92 | * `clz32()` ([a standalone shim is also available](https://npmjs.com/math.clz32))
93 | * `cosh()`
94 | * `expm1()`
95 | * `fround()` ([a standalone shim is also available](https://npmjs.com/math.fround))
96 | * `hypot()`
97 | * `imul()` ([a standalone shim is also available](https://npmjs.com/math.imul))
98 | * `log10()` ([a standalone shim is also available](https://npmjs.com/math.log10))
99 | * `log1p()` ([a standalone shim is also available](https://npmjs.com/math.log1p))
100 | * `log2()`
101 | * `sign()` ([a standalone shim is also available](https://npmjs.com/math.sign))
102 | * `sinh()`
103 | * `tanh()`
104 | * `trunc()`
105 |
106 | Math functions’ accuracy is 1e-11.
107 |
108 | * `Reflect`
109 | * `apply()` ([a standalone shim is also available](https://npmjs.com/reflect.apply))
110 | * `construct()`
111 | * `defineProperty()`
112 | * `deleteProperty()`
113 | * `get()`
114 | * `getOwnPropertyDescriptor()`
115 | * `getPrototypeOf()` ([a standalone shim is also available](https://npmjs.com/reflect.getprototypeof))
116 | * `has()`
117 | * `isExtensible()`
118 | * `ownKeys()` ([a standalone shim is also available](https://npmjs.com/reflect.ownkeys))
119 | * `preventExtensions()`
120 | * `set()`
121 | * `setPrototypeOf()`
122 |
123 | * `Symbol` (only if it already exists)
124 | * `match` (and corresponding `String#match`, `String#startsWith`, `String#endsWith`, `String#includes`, `RegExp` support)
125 | * `replace` (and corresponding `String#replace` support)
126 | * `search` (and corresponding `String#search` support)
127 | * `split` (and corresponding `String#split` support)
128 |
129 | Well-known symbols will only be provided if the engine already has `Symbol` support.
130 |
131 | * `String.prototype` Annex B HTML methods ([a standalone shim is also available](https://www.npmjs.com/package/es-string-html-methods))
132 | * `anchor()`
133 | * `big()`
134 | * `blink()`
135 | * `bold()`
136 | * `fixed()`
137 | * `fontcolor()`
138 | * `fontsize()`
139 | * `italics()`
140 | * `link()`
141 | * `small()`
142 | * `strike()`
143 | * `sub()`
144 | * `sup()`
145 |
146 | These methods are part of "Annex B", which means that although they are a defacto standard, you shouldn't use them. None the less, the `es6-shim` provides them and normalizes their behavior across browsers.
147 |
148 | ## Subclassing
149 | The `Map`, `Set`, and `Promise` implementations are subclassable.
150 | You should use the following pattern to create a subclass in ES5 which will continue to work in ES6:
151 | ```javascript
152 | require('es6-shim');
153 |
154 | function MyPromise(exec) {
155 | var promise = new Promise(exec);
156 | Object.setPrototypeOf(promise, MyPromise.prototype);
157 | // ...
158 | return promise;
159 | }
160 | Object.setPrototypeOf(MyPromise, Promise);
161 | MyPromise.prototype = Object.create(Promise.prototype, {
162 | constructor: { value: MyPromise }
163 | });
164 | ```
165 |
166 | ## String.prototype.normalize
167 | Including a proper shim for `String.prototype.normalize` would increase the size of this library by a factor of more than 4.
168 | So instead we recommend that you install the [`unorm`](https://github.com/walling/unorm) package alongside `es6-shim` if you need `String.prototype.normalize`.
169 | See https://github.com/paulmillr/es6-shim/issues/134 for more discussion.
170 |
171 |
172 | ## WeakMap shim
173 | It is not possible to implement WeakMap in pure javascript.
174 | The [es6-collections](https://github.com/WebReflection/es6-collections) implementation doesn't hold values strongly, which is critical for the collection. `es6-shim` decided to not include an incorrect shim.
175 |
176 | `WeakMap` has very unusual use-cases, so you probably won't need it at all (use simple `Map` instead).
177 |
178 | ## Getting started
179 |
180 | ```javascript
181 | require('es6-shim');
182 | var assert = require('assert');
183 |
184 | assert.equal(true, 'abc'.startsWith('a'));
185 | assert.equal(false, 'abc'.endsWith('a'));
186 | assert.equal(true, 'john alice'.includes('john'));
187 | assert.equal('123'.repeat(2), '123123');
188 |
189 | assert.equal(false, NaN === NaN);
190 | assert.equal(true, Object.is(NaN, NaN));
191 | assert.equal(true, -0 === 0);
192 | assert.equal(false, Object.is(-0, 0));
193 |
194 | var result = Object.assign({ a: 1 }, { b: 2 });
195 | assert.deepEqual(result, { a: 1, b: 2 });
196 |
197 | assert.equal(true, isNaN('a'));
198 | assert.equal(false, Number.isNaN('a'));
199 | assert.equal(true, Number.isNaN(NaN));
200 |
201 | assert.equal(true, isFinite('123'));
202 | assert.equal(false, Number.isFinite('123'));
203 | assert.equal(false, Number.isFinite(Infinity));
204 |
205 | // Tests if value is a number, finite,
206 | // >= -9007199254740992 && <= 9007199254740992 and floor(value) === value
207 | assert.equal(false, Number.isInteger(2.4));
208 |
209 | assert.equal(1, Math.sign(400));
210 | assert.equal(0, Math.sign(0));
211 | assert.equal(-1, Math.sign(-400));
212 |
213 | var found = [5, 10, 15, 10].find(function (item) { return item / 2 === 5; });
214 | assert.equal(10, found);
215 |
216 | var foundIndex = [5, 10, 15, 10].findIndex(function (item) { return item / 2 === 5; });
217 | assert.equal(1, foundIndex);
218 |
219 | // Replacement for `{}` key-value storage.
220 | // Keys can be anything.
221 | var map = new Map([['Bob', 42], ['Foo', 'bar']]);
222 | map.set('John', 25);
223 | map.set('Alice', 400);
224 | map.set(['meh'], 555);
225 | assert.equal(undefined, map.get(['meh'])); // undefined because you need to use exactly the same object.
226 | map.delete('Alice');
227 | map.keys();
228 | map.values();
229 | assert.equal(4, map.size);
230 |
231 | // Useful for storing unique items.
232 | var set = new Set([0, 1]);
233 | set.add(2);
234 | set.add(5);
235 | assert.equal(true, set.has(0));
236 | assert.equal(true, set.has(1));
237 | assert.equal(true, set.has(2));
238 | assert.equal(false, set.has(4));
239 | assert.equal(true, set.has(5));
240 | set.delete(5);
241 | assert.equal(false, set.has(5));
242 |
243 | // Promises, see
244 | // http://www.slideshare.net/domenicdenicola/callbacks-promises-and-coroutines-oh-my-the-evolution-of-asynchronicity-in-javascript
245 | // https://github.com/petkaantonov/bluebird/#what-are-promises-and-why-should-i-use-them
246 | Promise.resolve(5).then(function (value) {
247 | assert.equal(value, 5);
248 | if (value) throw new Error('whoops!');
249 | // do some stuff
250 | return anotherPromise();
251 | }).catch(function (e) {
252 | assert.equal(e.message, 'whoops!');
253 | assert.equal(true, e instanceof Error);
254 | // any errors thrown asynchronously end up here
255 | });
256 | ```
257 |
258 | ## Caveats
259 |
260 | - `Object.setPrototypeOf` / `Reflect.setPrototypeOf`
261 | - Note that null objects (`Object.create(null)`, eg, an object with `null` as its `[[Prototype]]`) can not have their `[[Prototype]]` changed except via a native `Object.setPrototypeOf`.
262 | - Well-known `Symbol`s
263 | - In order to make them work cross-realm, these are created with the global `Symbol` registry via `Symbol.for`. This does not violate the spec, but it does mean that `Symbol.for('Symbol.search') === Symbol.search` will be `true`, which it would not by default in a fresh compliant realm.
264 |
265 | ## [License][license-url]
266 |
267 | The project was initially based on es6-shim by Axel Rauschmayer.
268 |
269 | [license-url]: https://github.com/paulmillr/es6-shim/blob/master/LICENSE
270 | [spec-html-url]: http://www.ecma-international.org/ecma-262/6.0/
271 | [es5-shim-url]: https://github.com/es-shims/es5-shim
272 |
273 | [package-url]: https://npmjs.org/package/es6-shim
274 | [npm-version-svg]: https://versionbadg.es/paulmillr/es6-shim.svg
275 | [deps-svg]: https://david-dm.org/paulmillr/es6-shim.svg
276 | [deps-url]: https://david-dm.org/paulmillr/es6-shim
277 | [dev-deps-svg]: https://david-dm.org/paulmillr/es6-shim/dev-status.svg
278 | [dev-deps-url]: https://david-dm.org/paulmillr/es6-shim#info=devDependencies
279 | [npm-badge-png]: https://nodei.co/npm/es6-shim.png?downloads=true&stars=true
280 | [license-image]: https://img.shields.io/npm/l/es6-shim.svg
281 | [license-url]: LICENSE
282 | [downloads-image]: https://img.shields.io/npm/dm/es6-shim.svg
283 | [downloads-url]: https://npm-stat.com/charts.html?package=es6-shim
284 | [codecov-image]: https://codecov.io/gh/paulmillr/es6-shim/branch/main/graphs/badge.svg
285 | [codecov-url]: https://app.codecov.io/gh/paulmillr/es6-shim/
286 | [actions-image]: https://img.shields.io/endpoint?url=https://github-actions-badge-u3jn4tfpocch.runkit.sh/paulmillr/es6-shim
287 | [actions-url]: https://github.com/paulmillr/es6-shim/actions
288 |
--------------------------------------------------------------------------------
/bower.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "es6-shim",
3 | "repo": "paulmillr/es6-shim",
4 | "description": "ECMAScript 6 (Harmony) compatibility shims for legacy JavaScript engines",
5 | "keywords": [
6 | "ecmascript",
7 | "harmony",
8 | "es6",
9 | "shim",
10 | "promise",
11 | "promises",
12 | "setPrototypeOf",
13 | "map",
14 | "set",
15 | "__proto__"
16 | ],
17 | "main": "es6-shim.js",
18 | "scripts": ["es6-shim.js"],
19 | "dependencies": {},
20 | "development": {},
21 | "ignore": [
22 | "**/.*",
23 | "node_modules",
24 | "components",
25 | "test"
26 | ]
27 | }
28 |
29 |
--------------------------------------------------------------------------------
/component.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "es6-shim",
3 | "version": "0.35.3",
4 | "repo": "paulmillr/es6-shim",
5 | "description": "ECMAScript 6 (Harmony) compatibility shims for legacy JavaScript engines",
6 | "keywords": [
7 | "ecmascript",
8 | "harmony",
9 | "es6",
10 | "shim",
11 | "promise",
12 | "promises",
13 | "setPrototypeOf",
14 | "map",
15 | "set",
16 | "__proto__"
17 | ],
18 | "main": "es6-shim.js",
19 | "scripts": ["es6-shim.js"],
20 | "dependencies": {},
21 | "development": {}
22 | }
23 |
24 |
--------------------------------------------------------------------------------
/es6-sham.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * https://github.com/paulmillr/es6-shim
3 | * @license es6-shim Copyright 2013-2016 by Paul Miller (http://paulmillr.com)
4 | * and contributors, MIT License
5 | * es6-sham: v0.35.4
6 | * see https://github.com/paulmillr/es6-shim/blob/0.35.3/LICENSE
7 | * Details and documentation:
8 | * https://github.com/paulmillr/es6-shim/
9 | */
10 |
11 | // UMD (Universal Module Definition)
12 | // see https://github.com/umdjs/umd/blob/master/returnExports.js
13 | (function (root, factory) {
14 | /*global define */
15 | if (typeof define === 'function' && define.amd) {
16 | // AMD. Register as an anonymous module.
17 | define(factory);
18 | } else if (typeof exports === 'object') {
19 | // Node. Does not work with strict CommonJS, but
20 | // only CommonJS-like environments that support module.exports,
21 | // like Node.
22 | module.exports = factory();
23 | } else {
24 | // Browser globals (root is window)
25 | root.returnExports = factory();
26 | }
27 | }(this, function () {
28 | 'use strict';
29 |
30 | /* eslint-disable no-new-func */
31 | var getGlobal = new Function('return this;');
32 | /* eslint-enable no-new-func */
33 |
34 | var globals = getGlobal();
35 | var Object = globals.Object;
36 | var _call = Function.call.bind(Function.call);
37 | var functionToString = Function.toString;
38 | var _strMatch = String.prototype.match;
39 |
40 | var throwsError = function (func) {
41 | try {
42 | func();
43 | return false;
44 | } catch (e) {
45 | return true;
46 | }
47 | };
48 | var arePropertyDescriptorsSupported = function () {
49 | // if Object.defineProperty exists but throws, it's IE 8
50 | return !throwsError(function () {
51 | Object.defineProperty({}, 'x', { get: function () {} }); // eslint-disable-line getter-return
52 | });
53 | };
54 | var supportsDescriptors = !!Object.defineProperty && arePropertyDescriptorsSupported();
55 |
56 | // NOTE: This versions needs object ownership
57 | // because every promoted object needs to be reassigned
58 | // otherwise uncompatible browsers cannot work as expected
59 | //
60 | // NOTE: This might need es5-shim or polyfills upfront
61 | // because it's based on ES5 API.
62 | // (probably just an IE <= 8 problem)
63 | //
64 | // NOTE: nodejs is fine in version 0.8, 0.10, and future versions.
65 | (function () {
66 | if (Object.setPrototypeOf) { return; }
67 |
68 | // @author Andrea Giammarchi - @WebReflection
69 |
70 | var getOwnPropertyNames = Object.getOwnPropertyNames;
71 | var getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor;
72 | var create = Object.create;
73 | var defineProperty = Object.defineProperty;
74 | var getPrototypeOf = Object.getPrototypeOf;
75 | var objProto = Object.prototype;
76 |
77 | var copyDescriptors = function (target, source) {
78 | // define into target descriptors from source
79 | getOwnPropertyNames(source).forEach(function (key) {
80 | defineProperty(
81 | target,
82 | key,
83 | getOwnPropertyDescriptor(source, key)
84 | );
85 | });
86 | return target;
87 | };
88 | // used as fallback when no promotion is possible
89 | var createAndCopy = function (origin, proto) {
90 | return copyDescriptors(create(proto), origin);
91 | };
92 | var set, setPrototypeOf;
93 | try {
94 | // this might fail for various reasons
95 | // ignore if Chrome cought it at runtime
96 | set = getOwnPropertyDescriptor(objProto, '__proto__').set;
97 | set.call({}, null);
98 | // setter not poisoned, it can promote
99 | // Firefox, Chrome
100 | setPrototypeOf = function (origin, proto) {
101 | set.call(origin, proto);
102 | return origin;
103 | };
104 | } catch (e) {
105 | // do one or more feature detections
106 | set = { __proto__: null };
107 | // if proto does not work, needs to fallback
108 | // some Opera, Rhino, ducktape
109 | if (set instanceof Object) {
110 | setPrototypeOf = createAndCopy;
111 | } else {
112 | // verify if null objects are buggy
113 | /* eslint-disable no-proto */
114 | set.__proto__ = objProto;
115 | /* eslint-enable no-proto */
116 | // if null objects are buggy
117 | // nodejs 0.8 to 0.10
118 | if (set instanceof Object) {
119 | setPrototypeOf = function (origin, proto) {
120 | // use such bug to promote
121 | /* eslint-disable no-proto */
122 | origin.__proto__ = proto;
123 | /* eslint-enable no-proto */
124 | return origin;
125 | };
126 | } else {
127 | // try to use proto or fallback
128 | // Safari, old Firefox, many others
129 | setPrototypeOf = function (origin, proto) {
130 | // if proto is not null
131 | if (getPrototypeOf(origin)) {
132 | // use __proto__ to promote
133 | /* eslint-disable no-proto */
134 | origin.__proto__ = proto;
135 | /* eslint-enable no-proto */
136 | return origin;
137 | }
138 | // otherwise unable to promote: fallback
139 | return createAndCopy(origin, proto);
140 | };
141 | }
142 | }
143 | }
144 | Object.setPrototypeOf = setPrototypeOf;
145 | }());
146 |
147 | if (supportsDescriptors && function foo() {}.name !== 'foo') {
148 | /* eslint no-extend-native: 1 */
149 | Object.defineProperty(Function.prototype, 'name', {
150 | configurable: true,
151 | enumerable: false,
152 | get: function () {
153 | if (this === Function.prototype) {
154 | return '';
155 | }
156 | var str = _call(functionToString, this);
157 | var match = _call(_strMatch, str, /\s*function\s+([^(\s]*)\s*/);
158 | var name = match && match[1];
159 | Object.defineProperty(this, 'name', {
160 | configurable: true,
161 | enumerable: false,
162 | writable: false,
163 | value: name
164 | });
165 | return name;
166 | }
167 | });
168 | }
169 | }));
170 |
--------------------------------------------------------------------------------
/es6-sham.map:
--------------------------------------------------------------------------------
1 | {"version":3,"sources":["es6-sham.js"],"names":["root","factory","define","amd","exports","module","returnExports","this","getGlobal","Function","globals","Object","_call","call","bind","functionToString","toString","_strMatch","String","prototype","match","throwsError","func","e","arePropertyDescriptorsSupported","defineProperty","get","supportsDescriptors","setPrototypeOf","getOwnPropertyNames","getOwnPropertyDescriptor","create","getPrototypeOf","objProto","copyDescriptors","target","source","forEach","key","createAndCopy","origin","proto","set","__proto__","foo","name","configurable","enumerable","str","writable","value"],"mappings":";;;;;;;;;CAYC,SAAUA,EAAMC,GAEf,SAAWC,UAAW,YAAcA,OAAOC,IAAK,CAE9CD,OAAOD,OACF,UAAWG,WAAY,SAAU,CAItCC,OAAOD,QAAUH,QACZ,CAELD,EAAKM,cAAgBL,OAEvBM,KAAM,WACN,YAGA,IAAIC,GAAY,GAAIC,UAAS,eAG7B,IAAIC,GAAUF,GACd,IAAIG,GAASD,EAAQC,MACrB,IAAIC,GAAQH,SAASI,KAAKC,KAAKL,SAASI,KACxC,IAAIE,GAAmBN,SAASO,QAChC,IAAIC,GAAYC,OAAOC,UAAUC,KAEjC,IAAIC,GAAc,SAAUC,GAC1B,IACEA,GACA,OAAO,OACP,MAAOC,GACP,MAAO,OAGX,IAAIC,GAAkC,WAEpC,OAAQH,EAAY,WAClBV,EAAOc,kBAAmB,KAAOC,IAAK,iBAG1C,IAAIC,KAAwBhB,EAAOc,gBAAkBD,KAWpD,WACC,GAAIb,EAAOiB,eAAgB,CAAE,OAI7B,GAAIC,GAAsBlB,EAAOkB,mBACjC,IAAIC,GAA2BnB,EAAOmB,wBACtC,IAAIC,GAASpB,EAAOoB,MACpB,IAAIN,GAAiBd,EAAOc,cAC5B,IAAIO,GAAiBrB,EAAOqB,cAC5B,IAAIC,GAAWtB,EAAOQ,SAEtB,IAAIe,GAAkB,SAAUC,EAAQC,GAEtCP,EAAoBO,GAAQC,QAAQ,SAAUC,GAC5Cb,EACEU,EACAG,EACAR,EAAyBM,EAAQE,KAGrC,OAAOH,GAGT,IAAII,GAAgB,SAAUC,EAAQC,GACpC,MAAOP,GAAgBH,EAAOU,GAAQD,GAExC,IAAIE,GAAKd,CACT,KAGEc,EAAMZ,EAAyBG,EAAU,aAAaS,GACtDA,GAAI7B,QAAS,KAGbe,GAAiB,SAAUY,EAAQC,GACjCC,EAAI7B,KAAK2B,EAAQC,EACjB,OAAOD,IAET,MAAOjB,GAEPmB,GAAQC,UAAW,KAGnB,IAAID,YAAe/B,GAAQ,CACzBiB,EAAiBW,MACZ,CAGLG,EAAIC,UAAYV,CAIhB,IAAIS,YAAe/B,GAAQ,CACzBiB,EAAiB,SAAUY,EAAQC,GAGjCD,EAAOG,UAAYF,CAEnB,OAAOD,QAEJ,CAGLZ,EAAiB,SAAUY,EAAQC,GAEjC,GAAIT,EAAeQ,GAAS,CAG1BA,EAAOG,UAAYF,CAEnB,OAAOD,GAGT,MAAOD,GAAcC,EAAQC,MAKrC9B,EAAOiB,eAAiBA,KAG1B,IAAID,GAAuB,QAASiB,SAASC,OAAS,MAAO,CAE3DlC,EAAOc,eAAehB,SAASU,UAAW,QACxC2B,aAAc,KACdC,WAAY,MACZrB,IAAK,WACH,GAAInB,OAASE,SAASU,UAAW,CAC/B,MAAO,GAET,GAAI6B,GAAMpC,EAAMG,EAAkBR,KAClC,IAAIa,GAAQR,EAAMK,EAAW+B,EAAK,6BAClC,IAAIH,GAAOzB,GAASA,EAAM,EAC1BT,GAAOc,eAAelB,KAAM,QAC1BuC,aAAc,KACdC,WAAY,MACZE,SAAU,MACVC,MAAOL,GAET,OAAOA"}
--------------------------------------------------------------------------------
/es6-sham.min.js:
--------------------------------------------------------------------------------
1 | /*!
2 | * https://github.com/paulmillr/es6-shim
3 | * @license es6-shim Copyright 2013-2016 by Paul Miller (http://paulmillr.com)
4 | * and contributors, MIT License
5 | * es6-sham: v0.35.4
6 | * see https://github.com/paulmillr/es6-shim/blob/0.35.3/LICENSE
7 | * Details and documentation:
8 | * https://github.com/paulmillr/es6-shim/
9 | */
10 | (function(t,e){if(typeof define==="function"&&define.amd){define(e)}else if(typeof exports==="object"){module.exports=e()}else{t.returnExports=e()}})(this,function(){"use strict";var t=new Function("return this;");var e=t();var r=e.Object;var n=Function.call.bind(Function.call);var o=Function.toString;var i=String.prototype.match;var f=function(t){try{t();return false}catch(e){return true}};var u=function(){return!f(function(){r.defineProperty({},"x",{get:function(){}})})};var a=!!r.defineProperty&&u();(function(){if(r.setPrototypeOf){return}var t=r.getOwnPropertyNames;var e=r.getOwnPropertyDescriptor;var n=r.create;var o=r.defineProperty;var i=r.getPrototypeOf;var f=r.prototype;var u=function(r,n){t(n).forEach(function(t){o(r,t,e(n,t))});return r};var a=function(t,e){return u(n(e),t)};var c,p;try{c=e(f,"__proto__").set;c.call({},null);p=function(t,e){c.call(t,e);return t}}catch(s){c={__proto__:null};if(c instanceof r){p=a}else{c.__proto__=f;if(c instanceof r){p=function(t,e){t.__proto__=e;return t}}else{p=function(t,e){if(i(t)){t.__proto__=e;return t}return a(t,e)}}}}r.setPrototypeOf=p})();if(a&&function foo(){}.name!=="foo"){r.defineProperty(Function.prototype,"name",{configurable:true,enumerable:false,get:function(){if(this===Function.prototype){return""}var t=n(o,this);var e=n(i,t,/\s*function\s+([^(\s]*)\s*/);var f=e&&e[1];r.defineProperty(this,"name",{configurable:true,enumerable:false,writable:false,value:f});return f}})}});
11 | //# sourceMappingURL=es6-sham.map
12 |
--------------------------------------------------------------------------------
/node_modules/mocha/mocha.css:
--------------------------------------------------------------------------------
1 | @charset "utf-8";
2 |
3 | body {
4 | margin:0;
5 | }
6 |
7 | #mocha {
8 | font: 20px/1.5 "Helvetica Neue", Helvetica, Arial, sans-serif;
9 | margin: 60px 50px;
10 | }
11 |
12 | #mocha ul,
13 | #mocha li {
14 | margin: 0;
15 | padding: 0;
16 | }
17 |
18 | #mocha ul {
19 | list-style: none;
20 | }
21 |
22 | #mocha h1,
23 | #mocha h2 {
24 | margin: 0;
25 | }
26 |
27 | #mocha h1 {
28 | margin-top: 15px;
29 | font-size: 1em;
30 | font-weight: 200;
31 | }
32 |
33 | #mocha h1 a {
34 | text-decoration: none;
35 | color: inherit;
36 | }
37 |
38 | #mocha h1 a:hover {
39 | text-decoration: underline;
40 | }
41 |
42 | #mocha .suite .suite h1 {
43 | margin-top: 0;
44 | font-size: .8em;
45 | }
46 |
47 | #mocha .hidden {
48 | display: none;
49 | }
50 |
51 | #mocha h2 {
52 | font-size: 12px;
53 | font-weight: normal;
54 | cursor: pointer;
55 | }
56 |
57 | #mocha .suite {
58 | margin-left: 15px;
59 | }
60 |
61 | #mocha .test {
62 | margin-left: 15px;
63 | overflow: hidden;
64 | }
65 |
66 | #mocha .test.pending:hover h2::after {
67 | content: '(pending)';
68 | font-family: arial, sans-serif;
69 | }
70 |
71 | #mocha .test.pass.medium .duration {
72 | background: #c09853;
73 | }
74 |
75 | #mocha .test.pass.slow .duration {
76 | background: #b94a48;
77 | }
78 |
79 | #mocha .test.pass::before {
80 | content: '✓';
81 | font-size: 12px;
82 | display: block;
83 | float: left;
84 | margin-right: 5px;
85 | color: #00d6b2;
86 | }
87 |
88 | #mocha .test.pass .duration {
89 | font-size: 9px;
90 | margin-left: 5px;
91 | padding: 2px 5px;
92 | color: #fff;
93 | -webkit-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
94 | -moz-box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
95 | box-shadow: inset 0 1px 1px rgba(0,0,0,.2);
96 | -webkit-border-radius: 5px;
97 | -moz-border-radius: 5px;
98 | -ms-border-radius: 5px;
99 | -o-border-radius: 5px;
100 | border-radius: 5px;
101 | }
102 |
103 | #mocha .test.pass.fast .duration {
104 | display: none;
105 | }
106 |
107 | #mocha .test.pending {
108 | color: #0b97c4;
109 | }
110 |
111 | #mocha .test.pending::before {
112 | content: '◦';
113 | color: #0b97c4;
114 | }
115 |
116 | #mocha .test.fail {
117 | color: #c00;
118 | }
119 |
120 | #mocha .test.fail pre {
121 | color: black;
122 | }
123 |
124 | #mocha .test.fail::before {
125 | content: '✖';
126 | font-size: 12px;
127 | display: block;
128 | float: left;
129 | margin-right: 5px;
130 | color: #c00;
131 | }
132 |
133 | #mocha .test pre.error {
134 | color: #c00;
135 | max-height: 300px;
136 | overflow: auto;
137 | }
138 |
139 | #mocha .test .html-error {
140 | overflow: auto;
141 | color: black;
142 | line-height: 1.5;
143 | display: block;
144 | float: left;
145 | clear: left;
146 | font: 12px/1.5 monaco, monospace;
147 | margin: 5px;
148 | padding: 15px;
149 | border: 1px solid #eee;
150 | max-width: 85%; /*(1)*/
151 | max-width: -webkit-calc(100% - 42px);
152 | max-width: -moz-calc(100% - 42px);
153 | max-width: calc(100% - 42px); /*(2)*/
154 | max-height: 300px;
155 | word-wrap: break-word;
156 | border-bottom-color: #ddd;
157 | -webkit-box-shadow: 0 1px 3px #eee;
158 | -moz-box-shadow: 0 1px 3px #eee;
159 | box-shadow: 0 1px 3px #eee;
160 | -webkit-border-radius: 3px;
161 | -moz-border-radius: 3px;
162 | border-radius: 3px;
163 | }
164 |
165 | #mocha .test .html-error pre.error {
166 | border: none;
167 | -webkit-border-radius: 0;
168 | -moz-border-radius: 0;
169 | border-radius: 0;
170 | -webkit-box-shadow: 0;
171 | -moz-box-shadow: 0;
172 | box-shadow: 0;
173 | padding: 0;
174 | margin: 0;
175 | margin-top: 18px;
176 | max-height: none;
177 | }
178 |
179 | /**
180 | * (1): approximate for browsers not supporting calc
181 | * (2): 42 = 2*15 + 2*10 + 2*1 (padding + margin + border)
182 | * ^^ seriously
183 | */
184 | #mocha .test pre {
185 | display: block;
186 | float: left;
187 | clear: left;
188 | font: 12px/1.5 monaco, monospace;
189 | margin: 5px;
190 | padding: 15px;
191 | border: 1px solid #eee;
192 | max-width: 85%; /*(1)*/
193 | max-width: -webkit-calc(100% - 42px);
194 | max-width: -moz-calc(100% - 42px);
195 | max-width: calc(100% - 42px); /*(2)*/
196 | word-wrap: break-word;
197 | border-bottom-color: #ddd;
198 | -webkit-box-shadow: 0 1px 3px #eee;
199 | -moz-box-shadow: 0 1px 3px #eee;
200 | box-shadow: 0 1px 3px #eee;
201 | -webkit-border-radius: 3px;
202 | -moz-border-radius: 3px;
203 | border-radius: 3px;
204 | }
205 |
206 | #mocha .test h2 {
207 | position: relative;
208 | }
209 |
210 | #mocha .test a.replay {
211 | position: absolute;
212 | top: 3px;
213 | right: 0;
214 | text-decoration: none;
215 | vertical-align: middle;
216 | display: block;
217 | width: 15px;
218 | height: 15px;
219 | line-height: 15px;
220 | text-align: center;
221 | background: #eee;
222 | font-size: 15px;
223 | -webkit-border-radius: 15px;
224 | -moz-border-radius: 15px;
225 | border-radius: 15px;
226 | -webkit-transition:opacity 200ms;
227 | -moz-transition:opacity 200ms;
228 | -o-transition:opacity 200ms;
229 | transition: opacity 200ms;
230 | opacity: 0.3;
231 | color: #888;
232 | }
233 |
234 | #mocha .test:hover a.replay {
235 | opacity: 1;
236 | }
237 |
238 | #mocha-report.pass .test.fail {
239 | display: none;
240 | }
241 |
242 | #mocha-report.fail .test.pass {
243 | display: none;
244 | }
245 |
246 | #mocha-report.pending .test.pass,
247 | #mocha-report.pending .test.fail {
248 | display: none;
249 | }
250 | #mocha-report.pending .test.pass.pending {
251 | display: block;
252 | }
253 |
254 | #mocha-error {
255 | color: #c00;
256 | font-size: 1.5em;
257 | font-weight: 100;
258 | letter-spacing: 1px;
259 | }
260 |
261 | #mocha-stats {
262 | position: fixed;
263 | top: 15px;
264 | right: 10px;
265 | font-size: 12px;
266 | margin: 0;
267 | color: #888;
268 | z-index: 1;
269 | }
270 |
271 | #mocha-stats .progress {
272 | float: right;
273 | padding-top: 0;
274 |
275 | /**
276 | * Set safe initial values, so mochas .progress does not inherit these
277 | * properties from Bootstrap .progress (which causes .progress height to
278 | * equal line height set in Bootstrap).
279 | */
280 | height: auto;
281 | -webkit-box-shadow: none;
282 | -moz-box-shadow: none;
283 | box-shadow: none;
284 | background-color: initial;
285 | }
286 |
287 | #mocha-stats em {
288 | color: black;
289 | }
290 |
291 | #mocha-stats a {
292 | text-decoration: none;
293 | color: inherit;
294 | }
295 |
296 | #mocha-stats a:hover {
297 | border-bottom: 1px solid #eee;
298 | }
299 |
300 | #mocha-stats li {
301 | display: inline-block;
302 | margin: 0 5px;
303 | list-style: none;
304 | padding-top: 11px;
305 | }
306 |
307 | #mocha-stats canvas {
308 | width: 40px;
309 | height: 40px;
310 | }
311 |
312 | #mocha code .comment { color: #ddd; }
313 | #mocha code .init { color: #2f6fad; }
314 | #mocha code .string { color: #5890ad; }
315 | #mocha code .keyword { color: #8a6343; }
316 | #mocha code .number { color: #2f6fad; }
317 |
318 | @media screen and (max-device-width: 480px) {
319 | #mocha {
320 | margin: 60px 0px;
321 | }
322 |
323 | #mocha #stats {
324 | position: absolute;
325 | }
326 | }
327 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "es6-shim",
3 | "version": "0.35.8",
4 | "author": "Paul Miller (http://paulmillr.com)",
5 | "description": "ECMAScript 6 (Harmony) compatibility shims for legacy JavaScript engines",
6 | "keywords": [
7 | "ecmascript",
8 | "harmony",
9 | "es6",
10 | "shim",
11 | "promise",
12 | "promises",
13 | "setPrototypeOf",
14 | "map",
15 | "set",
16 | "__proto__"
17 | ],
18 | "homepage": "https://github.com/paulmillr/es6-shim/",
19 | "license": "MIT",
20 | "repository": {
21 | "type": "git",
22 | "url": "git://github.com/paulmillr/es6-shim.git"
23 | },
24 | "main": "es6-shim",
25 | "scripts": {
26 | "prepublishOnly": "safe-publish-latest && npm run minify",
27 | "prepublih": "not-in-publish || npm run prepublishOnly",
28 | "pretest": "npm run lint && evalmd *.md",
29 | "test": "NODE_OPTIONS='--unhandled-rejections=none' npm run tests-only",
30 | "posttest": "aud --production",
31 | "tests-only": "nyc mocha 'test/**/*.js' 'test-sham/*.js'",
32 | "test:shim": "nyc mocha 'test/**/*.js'",
33 | "test:sham": "nyc mocha 'test-sham/*.js'",
34 | "test:native": "NO_ES6_SHIM=1 npm run tests-only",
35 | "lint": "npm run lint:shim && npm run lint:sham",
36 | "lint:shim": "eslint es6-shim.js test/*.js test/*/*.js",
37 | "lint:sham": "eslint es6-sham.js test-sham/*.js",
38 | "minify": "npm run minify:shim && npm run minify:sham",
39 | "minify:shim": "uglifyjs es6-shim.js --support-ie8 --keep-fnames --comments --source-map=es6-shim.map -m -b ascii_only=true,beautify=false > es6-shim.min.js",
40 | "minify:sham": "uglifyjs es6-sham.js --support-ie8 --keep-fnames --comments --source-map=es6-sham.map -m -b ascii_only=true,beautify=false > es6-sham.min.js",
41 | "sauce-connect": "curl -L https://gist.githubusercontent.com/henrikhodne/9322897/raw/sauce-connect.sh | bash && export TRAVIS_SAUCE_CONNECT=true",
42 | "sauce": "npm run sauce-connect && grunt sauce"
43 | },
44 | "testling": {
45 | "html": "testling.html",
46 | "browsers": [
47 | "iexplore/6.0..latest",
48 | "firefox/3.0..6.0",
49 | "firefox/10.0",
50 | "firefox/15.0..latest",
51 | "firefox/nightly",
52 | "chrome/4.0..10.0",
53 | "chrome/20.0..latest",
54 | "chrome/canary",
55 | "opera/10.0..latest",
56 | "opera/next",
57 | "safari/4.0..latest",
58 | "ipad/6.0..latest",
59 | "iphone/6.0..latest",
60 | "android-browser/4.2..latest"
61 | ]
62 | },
63 | "devDependencies": {
64 | "@ljharb/eslint-config": "^21.0.1",
65 | "aud": "^2.0.2",
66 | "chai": "^3.5.0",
67 | "es5-shim": "^4.6.7",
68 | "eslint": "=8.8.0",
69 | "evalmd": "^0.0.19",
70 | "grunt": "^0.4.5",
71 | "grunt-contrib-connect": "^1.0.2",
72 | "grunt-contrib-watch": "^1.1.0",
73 | "grunt-saucelabs": "^8.6.3",
74 | "in-publish": "^2.0.1",
75 | "mocha": "^3.5.3",
76 | "nyc": "^10.3.2",
77 | "promises-aplus-tests": "^2.1.2",
78 | "promises-es6-tests": "^0.5.0",
79 | "safe-publish-latest": "^2.0.0",
80 | "tape": "^5.6.3",
81 | "uglify-js": "2.7.3"
82 | },
83 | "engines": {
84 | "node": ">= 0.4"
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/test-sham/function.js:
--------------------------------------------------------------------------------
1 | var identity = function (x) { return x; };
2 |
3 | describe('Function', function () {
4 | describe('#name', function () {
5 | it('returns the name for named functions', function () {
6 | var foo = function bar() {};
7 | expect(foo.name).to.equal('bar');
8 |
9 | // pre-ES6, this property is nonconfigurable.
10 | var configurable = Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(foo, 'name').configurable : false;
11 |
12 | expect(foo).to.have.ownPropertyDescriptor('name', {
13 | configurable: !!configurable,
14 | enumerable: false,
15 | writable: false,
16 | value: 'bar'
17 | });
18 | });
19 |
20 | it('does not poison every name when accessed on Function.prototype', function () {
21 | expect((function foo() {}).name).to.equal('foo');
22 | expect(Function.prototype.name).to.match(/^$|Empty/);
23 | expect((function foo() {}).name).to.equal('foo');
24 | });
25 |
26 | it('returns empty string for anonymous functions', function () {
27 | var anon = identity(function () {});
28 | expect(anon.name).to.equal('');
29 |
30 | // pre-ES6, this property is nonconfigurable.
31 | var configurable = Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(anon, 'name').configurable : false;
32 |
33 | expect(anon).to.have.ownPropertyDescriptor('name', {
34 | configurable: !!configurable,
35 | enumerable: false,
36 | writable: false,
37 | value: ''
38 | });
39 | });
40 |
41 | it('returns "anomymous" for Function functions', function () {
42 | // eslint-disable-next-line no-new-func
43 | var func = identity(Function(''));
44 | expect(typeof func.name).to.equal('string');
45 | expect(func.name === 'anonymous' || func.name === '').to.equal(true);
46 |
47 | // pre-ES6, this property is nonconfigurable.
48 | var configurable = Object.getOwnPropertyDescriptor ? Object.getOwnPropertyDescriptor(func, 'name').configurable : false;
49 |
50 | expect(func).to.have.ownPropertyDescriptor('name', {
51 | configurable: !!configurable,
52 | enumerable: false,
53 | writable: false,
54 | value: func.name
55 | });
56 | });
57 | });
58 | });
59 |
--------------------------------------------------------------------------------
/test-sham/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | es6-shim tests
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/test-sham/set-prototype-of.js:
--------------------------------------------------------------------------------
1 | describe('Object.setPrototypeOf(o, p)', function () {
2 | 'use strict';
3 |
4 | it('changes prototype to regular objects', function () {
5 | var obj = { a: 123 };
6 | expect(obj instanceof Object).to.equal(true);
7 | // sham requires assignment to work cross browser
8 | obj = Object.setPrototypeOf(obj, null);
9 | expect(obj instanceof Object).to.equal(false);
10 | expect(obj.a).to.equal(123);
11 | });
12 |
13 | it('changes prototype to null objects', function () {
14 | var obj = Object.create(null);
15 | obj.a = 456;
16 | expect(obj instanceof Object).to.equal(false);
17 | expect(obj.a).to.equal(456);
18 | // sham requires assignment to work cross browser
19 | obj = Object.setPrototypeOf(obj, { b: 789 });
20 | expect(obj instanceof Object).to.equal(true);
21 | expect(obj.a).to.equal(456);
22 | expect(obj.b).to.equal(789);
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/test/browser-onload.js:
--------------------------------------------------------------------------------
1 | if (typeof window !== 'undefined') {
2 | window.completedTests = 0;
3 | window.sawFail = false;
4 | window.onload = function () {
5 | window.testsPassed = null;
6 | var handleResults = function (runner) {
7 | var failedTests = [];
8 | if (runner.stats.end) {
9 | window.testsPassed = runner.stats.failures === 0;
10 | }
11 | runner.on('pass', function () {
12 | window.completedTests += 1;
13 | });
14 | runner.on('fail', function (test, err) {
15 | window.sawFail = true;
16 | var flattenTitles = function (testToFlatten) {
17 | var titles = [];
18 | var currentTest = testToFlatten;
19 | while (currentTest.parent.title) {
20 | titles.push(currentTest.parent.title);
21 | currentTest = currentTest.parent;
22 | }
23 | return titles.reverse();
24 | };
25 | failedTests.push({
26 | name: test.title,
27 | result: false,
28 | message: err.message,
29 | stack: err.stack,
30 | titles: flattenTitles(test)
31 | });
32 | });
33 | runner.on('end', function () {
34 | window.testsPassed = !window.sawFail;
35 | // for sauce
36 | window.mochaResults = runner.stats;
37 | window.mochaResults.reports = failedTests;
38 | });
39 | return runner;
40 | };
41 | handleResults(mocha.run());
42 | };
43 | }
44 |
--------------------------------------------------------------------------------
/test/browser-setup.js:
--------------------------------------------------------------------------------
1 | if (typeof window !== 'undefined') {
2 | chai.config.includeStack = true;
3 | window.expect = chai.expect;
4 | window.assert = chai.assert;
5 | mocha.setup('bdd');
6 | window.require = function () {
7 | return window;
8 | };
9 | }
10 |
--------------------------------------------------------------------------------
/test/date.js:
--------------------------------------------------------------------------------
1 | describe('Date', function () {
2 | it('when invalid, dates should toString to "Invalid Date"', function () {
3 | expect(String(new Date(NaN))).to.equal('Invalid Date');
4 | });
5 | });
6 |
--------------------------------------------------------------------------------
/test/google-translate.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | es6-shim tests
6 |
7 |
8 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
--------------------------------------------------------------------------------
/test/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | es6-shim tests
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/test/json.js:
--------------------------------------------------------------------------------
1 | describe('JSON', function () {
2 | var functionsHaveNames = (function foo() {}).name === 'foo';
3 | var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
4 | var hasSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol';
5 | var ifSymbolsIt = hasSymbols ? it : xit;
6 | var ifSymbolsDescribe = hasSymbols ? describe : xit;
7 |
8 | describe('.stringify()', function () {
9 | ifFunctionsHaveNamesIt('has the right name', function () {
10 | expect(JSON.stringify.name).to.equal('stringify');
11 | });
12 |
13 | ifSymbolsIt('serializes a Symbol to undefined', function () {
14 | expect(JSON.stringify(Symbol())).to.equal(undefined);
15 | });
16 |
17 | ifSymbolsIt('serializes a Symbol object to {}', function () {
18 | expect(function stringifyObjectSymbol() { JSON.stringify(Object(Symbol())); }).not.to['throw']();
19 | expect(JSON.stringify(Object(Symbol()))).to.equal('{}');
20 | });
21 |
22 | ifSymbolsIt('serializes Symbols in an Array to null', function () {
23 | expect(JSON.stringify([Symbol('foo')])).to.equal('[null]');
24 | });
25 |
26 | ifSymbolsIt('serializes Symbol objects in an Array to {}', function () {
27 | expect(function stringifyObjectSymbolInArray() { JSON.stringify([Object(Symbol('foo'))]); }).not.to['throw']();
28 | expect(JSON.stringify([Object(Symbol('foo'))])).to.equal('[{}]');
29 | });
30 |
31 | ifSymbolsDescribe('skips symbol properties and values in an object', function () {
32 | var enumSym = Symbol('enumerable');
33 | var nonenum = Symbol('non-enumerable');
34 | var createObject = function () {
35 | var obj = { a: 1 };
36 | obj[enumSym] = true;
37 | obj.sym = enumSym;
38 | Object.defineProperty(obj, nonenum, { enumerable: false, value: true });
39 | expect(Object.getOwnPropertySymbols(obj)).to.eql([enumSym, nonenum]);
40 | return obj;
41 | };
42 |
43 | it('works with no replacer', function () {
44 | var obj = createObject();
45 | expect(JSON.stringify(obj)).to.equal('{"a":1}');
46 | expect(JSON.stringify(obj, null, '|')).to.equal('{\n|"a": 1\n}');
47 | });
48 |
49 | it('works with a replacer function', function () {
50 | var tuples = [];
51 | var replacer = function (key, value) {
52 | tuples.push([this, key, value]);
53 | return value;
54 | };
55 | var obj = createObject();
56 | expect(JSON.stringify(obj, replacer, '|')).to.equal('{\n|"a": 1\n}'); // populate `tuples` array
57 | expect(tuples).to.eql([
58 | [{ '': obj }, '', obj],
59 | [obj, 'a', 1],
60 | [obj, 'sym', enumSym]
61 | ]);
62 | });
63 |
64 | it('works with a replacer array', function () {
65 | var obj = createObject();
66 | obj.foo = 'bar';
67 | obj[Symbol.prototype.toString.call(enumSym)] = 'tricksy';
68 | expect(JSON.stringify(obj, ['a', enumSym])).to.equal('{"a":1}');
69 | expect(JSON.stringify(obj, ['a', enumSym], '|')).to.equal('{\n|"a": 1\n}');
70 | });
71 |
72 | it('ignores a non-array non-callable replacer object', function () {
73 | expect(JSON.stringify('z', { test: null })).to.equal('"z"');
74 | });
75 | });
76 | });
77 | });
78 |
--------------------------------------------------------------------------------
/test/map.js:
--------------------------------------------------------------------------------
1 | // Big thanks to V8 folks for test ideas.
2 | // v8/test/mjsunit/harmony/collections.js
3 |
4 | var Assertion = expect().constructor;
5 | Assertion.addMethod('theSameSet', function (otherArray) {
6 | var array = this._obj;
7 |
8 | expect(Array.isArray(array)).to.equal(true);
9 | expect(Array.isArray(otherArray)).to.equal(true);
10 |
11 | var diff = array.filter(function (value) {
12 | return otherArray.every(function (otherValue) {
13 | var areBothNaN = typeof value === 'number' && typeof otherValue === 'number' && value !== value && otherValue !== otherValue;
14 | return !areBothNaN && value !== otherValue;
15 | });
16 | });
17 |
18 | this.assert(
19 | diff.length === 0,
20 | 'expected #{this} to be equal to #{exp} (as sets, i.e. no order)',
21 | array,
22 | otherArray
23 | );
24 | });
25 |
26 | Assertion.addMethod('entries', function (expected) {
27 | var collection = this._obj;
28 |
29 | expect(Array.isArray(expected)).to.equal(true);
30 | var expectedEntries = expected.slice();
31 |
32 | var iterator = collection.entries();
33 | var result;
34 | do {
35 | result = iterator.next();
36 | expect(result.value).to.be.eql(expectedEntries.shift());
37 | } while (!result.done);
38 | });
39 |
40 | describe('Map', function () {
41 | var functionsHaveNames = (function foo() {}).name === 'foo';
42 | var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
43 | var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
44 | var ifGetPrototypeOfIt = Object.getPrototypeOf ? it : xit;
45 |
46 | var range = function range(from, to) {
47 | var result = [];
48 | for (var value = from; value < to; value++) {
49 | result.push(value);
50 | }
51 | return result;
52 | };
53 |
54 | var prototypePropIsEnumerable = Object.prototype.propertyIsEnumerable.call(function () {}, 'prototype');
55 | var expectNotEnumerable = function (object) {
56 | if (prototypePropIsEnumerable && typeof object === 'function') {
57 | expect(Object.keys(object)).to.eql(['prototype']);
58 | } else {
59 | expect(Object.keys(object)).to.eql([]);
60 | }
61 | };
62 |
63 | var Sym = typeof Symbol === 'undefined' ? {} : Symbol;
64 | var isSymbol = function (sym) {
65 | return typeof Sym === 'function' && typeof sym === 'symbol';
66 | };
67 | var ifSymbolIteratorIt = isSymbol(Sym.iterator) ? it : xit;
68 |
69 | var testMapping = function (map, key, value) {
70 | expect(map.has(key)).to.equal(false);
71 | expect(map.get(key)).to.equal(undefined);
72 | expect(map.set(key, value)).to.equal(map);
73 | expect(map.get(key)).to.equal(value);
74 | expect(map.has(key)).to.equal(true);
75 | };
76 |
77 | if (typeof Map === 'undefined') {
78 | return it('exists', function () {
79 | expect(typeof Map).to.equal('function');
80 | });
81 | }
82 |
83 | var map;
84 | beforeEach(function () {
85 | map = new Map();
86 | });
87 |
88 | afterEach(function () {
89 | map = null;
90 | });
91 |
92 | ifShimIt('is on the exported object', function () {
93 | var exported = require('../');
94 | expect(exported.Map).to.equal(Map);
95 | });
96 |
97 | it('should exist in global namespace', function () {
98 | expect(typeof Map).to.equal('function');
99 | });
100 |
101 | it('should have the right arity', function () {
102 | expect(Map).to.have.property('length', 0);
103 | });
104 |
105 | it('should has valid getter and setter calls', function () {
106 | ['get', 'set', 'has', 'delete'].forEach(function (method) {
107 | expect(function () {
108 | map[method]({});
109 | }).to.not['throw']();
110 | });
111 | });
112 |
113 | it('should accept an iterable as argument', function () {
114 | testMapping(map, 'a', 'b');
115 | testMapping(map, 'c', 'd');
116 | var map2;
117 | expect(function () { map2 = new Map(map); }).not.to['throw'](Error);
118 | expect(map2).to.be.an.instanceOf(Map);
119 | expect(map2.has('a')).to.equal(true);
120 | expect(map2.has('c')).to.equal(true);
121 | expect(map2).to.have.entries([['a', 'b'], ['c', 'd']]);
122 | });
123 |
124 | it('should throw with iterables that return primitives', function () {
125 | expect(function () { return new Map('123'); }).to['throw'](TypeError);
126 | expect(function () { return new Map([1, 2, 3]); }).to['throw'](TypeError);
127 | expect(function () { return new Map(['1', '2', '3']); }).to['throw'](TypeError);
128 | expect(function () { return new Map([true]); }).to['throw'](TypeError);
129 | });
130 |
131 | it('should not be callable without "new"', function () {
132 | expect(Map).to['throw'](TypeError);
133 | });
134 |
135 | it('should be subclassable', function () {
136 | if (!Object.setPrototypeOf) { return; } // skip test if on IE < 11
137 | var MyMap = function MyMap() {
138 | var testMap = new Map([['a', 'b']]);
139 | Object.setPrototypeOf(testMap, MyMap.prototype);
140 | return testMap;
141 | };
142 | Object.setPrototypeOf(MyMap, Map);
143 | MyMap.prototype = Object.create(Map.prototype, {
144 | constructor: { value: MyMap }
145 | });
146 |
147 | var myMap = new MyMap();
148 | testMapping(myMap, 'c', 'd');
149 | expect(myMap).to.have.entries([['a', 'b'], ['c', 'd']]);
150 | });
151 |
152 | it('uses SameValueZero even on a Map of size > 4', function () {
153 | // Chrome 38-42, node 0.11/0.12, iojs 1/2 have a bug when the Map has a size > 4
154 | var firstFour = [[1, 0], [2, 0], [3, 0], [4, 0]];
155 | var fourMap = new Map(firstFour);
156 | expect(fourMap.size).to.equal(4);
157 | expect(fourMap.has(-0)).to.equal(false);
158 | expect(fourMap.has(0)).to.equal(false);
159 |
160 | fourMap.set(-0, fourMap);
161 |
162 | expect(fourMap.has(0)).to.equal(true);
163 | expect(fourMap.has(-0)).to.equal(true);
164 | });
165 |
166 | it('treats positive and negative zero the same', function () {
167 | var value1 = {};
168 | var value2 = {};
169 | testMapping(map, +0, value1);
170 | expect(map.has(-0)).to.equal(true);
171 | expect(map.get(-0)).to.equal(value1);
172 | expect(map.set(-0, value2)).to.equal(map);
173 | expect(map.get(-0)).to.equal(value2);
174 | expect(map.get(+0)).to.equal(value2);
175 | });
176 |
177 | it('should map values correctly', function () {
178 | // Run this test twice, one with the "fast" implementation (which only
179 | // allows string and numeric keys) and once with the "slow" impl.
180 | [true, false].forEach(function (slowkeys) {
181 | map = new Map();
182 |
183 | range(1, 20).forEach(function (number) {
184 | if (slowkeys) { testMapping(map, number, {}); }
185 | testMapping(map, number / 100, {});
186 | testMapping(map, 'key-' + number, {});
187 | testMapping(map, String(number), {});
188 | if (slowkeys) { testMapping(map, Object(String(number)), {}); }
189 | });
190 |
191 | var testkeys = [Infinity, -Infinity, NaN];
192 | if (slowkeys) {
193 | testkeys.push(true, false, null, undefined);
194 | }
195 | testkeys.forEach(function (key) {
196 | testMapping(map, key, {});
197 | testMapping(map, String(key), {});
198 | });
199 | testMapping(map, '', {});
200 |
201 | // verify that properties of Object don't peek through.
202 | [
203 | 'hasOwnProperty',
204 | 'constructor',
205 | 'toString',
206 | 'isPrototypeOf',
207 | '__proto__',
208 | '__parent__',
209 | '__count__'
210 | ].forEach(function (key) {
211 | testMapping(map, key, {});
212 | });
213 | });
214 | });
215 |
216 | it('should map empty values correctly', function () {
217 | testMapping(map, {}, true);
218 | testMapping(map, null, true);
219 | testMapping(map, undefined, true);
220 | testMapping(map, '', true);
221 | testMapping(map, NaN, true);
222 | testMapping(map, 0, true);
223 | });
224 |
225 | it('should has correct querying behavior', function () {
226 | var key = {};
227 | testMapping(map, key, 'to-be-present');
228 | expect(map.has(key)).to.equal(true);
229 | expect(map.has({})).to.equal(false);
230 | expect(map.set(key, void 0)).to.equal(map);
231 | expect(map.get(key)).to.equal(undefined);
232 | expect(map.has(key)).to.equal(true);
233 | expect(map.has({})).to.equal(false);
234 | });
235 |
236 | it('should allow NaN values as keys', function () {
237 | expect(map.has(NaN)).to.equal(false);
238 | expect(map.has(NaN + 1)).to.equal(false);
239 | expect(map.has(23)).to.equal(false);
240 | expect(map.set(NaN, 'value')).to.equal(map);
241 | expect(map.has(NaN)).to.equal(true);
242 | expect(map.has(NaN + 1)).to.equal(true);
243 | expect(map.has(23)).to.equal(false);
244 | });
245 |
246 | it('should not have [[Enumerable]] props', function () {
247 | expectNotEnumerable(Map);
248 | expectNotEnumerable(Map.prototype);
249 | expectNotEnumerable(new Map());
250 | });
251 |
252 | it('should not have an own constructor', function () {
253 | var m = new Map();
254 | expect(m).not.to.haveOwnPropertyDescriptor('constructor');
255 | expect(m.constructor).to.equal(Map);
256 | });
257 |
258 | it('should allow common ecmascript idioms', function () {
259 | expect(map).to.be.an.instanceOf(Map);
260 | expect(typeof Map.prototype.get).to.equal('function');
261 | expect(typeof Map.prototype.set).to.equal('function');
262 | expect(typeof Map.prototype.has).to.equal('function');
263 | expect(typeof Map.prototype['delete']).to.equal('function');
264 | });
265 |
266 | it('should have a unique constructor', function () {
267 | expect(Map.prototype).to.not.equal(Object.prototype);
268 | });
269 |
270 | describe('#clear()', function () {
271 | ifFunctionsHaveNamesIt('has the right name', function () {
272 | expect(Map.prototype.clear).to.have.property('name', 'clear');
273 | });
274 |
275 | it('is not enumerable', function () {
276 | expect(Map.prototype).ownPropertyDescriptor('clear').to.have.property('enumerable', false);
277 | });
278 |
279 | it('has the right arity', function () {
280 | expect(Map.prototype.clear).to.have.property('length', 0);
281 | });
282 |
283 | it('should have #clear method', function () {
284 | expect(map.set(1, 2)).to.equal(map);
285 | expect(map.set(5, 2)).to.equal(map);
286 | expect(map.size).to.equal(2);
287 | expect(map.has(5)).to.equal(true);
288 | map.clear();
289 | expect(map.size).to.equal(0);
290 | expect(map.has(5)).to.equal(false);
291 | });
292 | });
293 |
294 | describe('#keys()', function () {
295 | if (!Object.prototype.hasOwnProperty.call(Map.prototype, 'keys')) {
296 | return it('exists', function () {
297 | expect(Map.prototype).to.have.property('keys');
298 | });
299 | }
300 |
301 | ifFunctionsHaveNamesIt('has the right name', function () {
302 | expect(Map.prototype.keys).to.have.property('name', 'keys');
303 | });
304 |
305 | it('is not enumerable', function () {
306 | expect(Map.prototype).ownPropertyDescriptor('keys').to.have.property('enumerable', false);
307 | });
308 |
309 | it('has the right arity', function () {
310 | expect(Map.prototype.keys).to.have.property('length', 0);
311 | });
312 | });
313 |
314 | describe('#values()', function () {
315 | if (!Object.prototype.hasOwnProperty.call(Map.prototype, 'values')) {
316 | return it('exists', function () {
317 | expect(Map.prototype).to.have.property('values');
318 | });
319 | }
320 |
321 | ifFunctionsHaveNamesIt('has the right name', function () {
322 | expect(Map.prototype.values).to.have.property('name', 'values');
323 | });
324 |
325 | it('is not enumerable', function () {
326 | expect(Map.prototype).ownPropertyDescriptor('values').to.have.property('enumerable', false);
327 | });
328 |
329 | it('has the right arity', function () {
330 | expect(Map.prototype.values).to.have.property('length', 0);
331 | });
332 | });
333 |
334 | describe('#entries()', function () {
335 | if (!Object.prototype.hasOwnProperty.call(Map.prototype, 'entries')) {
336 | return it('exists', function () {
337 | expect(Map.prototype).to.have.property('entries');
338 | });
339 | }
340 |
341 | ifFunctionsHaveNamesIt('has the right name', function () {
342 | expect(Map.prototype.entries).to.have.property('name', 'entries');
343 | });
344 |
345 | it('is not enumerable', function () {
346 | expect(Map.prototype).ownPropertyDescriptor('entries').to.have.property('enumerable', false);
347 | });
348 |
349 | it('has the right arity', function () {
350 | expect(Map.prototype.entries).to.have.property('length', 0);
351 | });
352 |
353 | it('throws when called on a non-Map', function () {
354 | var expectedMessage = /^(Method )?Map.prototype.entries called on incompatible receiver |^entries method called on incompatible |^Cannot create a Map entry iterator for a non-Map object.|^Map\.prototype\.entries: 'this' is not a Map object$|^std_Map_iterator method called on incompatible \w$|Map.prototype.entries requires that \|this\| be Map+$|is not an object \(evaluating 'Map.prototype.entries.call\(nonMap\)'\)|Map operation called on non-Map object/;
355 | var nonMaps = [true, false, 'abc', NaN, new Set([1, 2]), { a: true }, [1], Object('abc'), Object(NaN)];
356 | nonMaps.forEach(function (nonMap) {
357 | expect(function () { return Map.prototype.entries.call(nonMap); }).to['throw'](TypeError, expectedMessage);
358 | });
359 | });
360 | });
361 |
362 | describe('#size', function () {
363 | it('throws TypeError when accessed directly', function () {
364 | // see https://github.com/paulmillr/es6-shim/issues/176
365 | expect(function () { return Map.prototype.size; }).to['throw'](TypeError);
366 | expect(function () { return Map.prototype.size; }).to['throw'](TypeError);
367 | });
368 |
369 | it('is an accessor function on the prototype', function () {
370 | expect(Map.prototype).ownPropertyDescriptor('size').to.have.property('get');
371 | expect(typeof Object.getOwnPropertyDescriptor(Map.prototype, 'size').get).to.equal('function');
372 | expect(new Map()).not.to.haveOwnPropertyDescriptor('size');
373 | });
374 | });
375 |
376 | it('should return false when deleting a nonexistent key', function () {
377 | expect(map.has('a')).to.equal(false);
378 | expect(map['delete']('a')).to.equal(false);
379 | });
380 |
381 | it('should have keys, values and size props', function () {
382 | expect(map.set('a', 1)).to.equal(map);
383 | expect(map.set('b', 2)).to.equal(map);
384 | expect(map.set('c', 3)).to.equal(map);
385 | expect(typeof map.keys).to.equal('function');
386 | expect(typeof map.values).to.equal('function');
387 | expect(map.size).to.equal(3);
388 | expect(map['delete']('a')).to.equal(true);
389 | expect(map.size).to.equal(2);
390 | });
391 |
392 | it('should have an iterator that works with Array.from', function () {
393 | expect(Array).to.have.property('from');
394 |
395 | expect(map.set('a', 1)).to.equal(map);
396 | expect(map.set('b', NaN)).to.equal(map);
397 | expect(map.set('c', false)).to.equal(map);
398 | expect(Array.from(map)).to.eql([['a', 1], ['b', NaN], ['c', false]]);
399 | expect(Array.from(map.keys())).to.eql(['a', 'b', 'c']);
400 | expect(Array.from(map.values())).to.eql([1, NaN, false]);
401 | expect(map).to.have.entries(Array.from(map.entries()));
402 | });
403 |
404 | ifSymbolIteratorIt('has the right default iteration function', function () {
405 | // fixed in Webkit https://bugs.webkit.org/show_bug.cgi?id=143838
406 | expect(Map.prototype).to.have.property(Sym.iterator, Map.prototype.entries);
407 | });
408 |
409 | describe('#forEach', function () {
410 | var mapToIterate;
411 |
412 | beforeEach(function () {
413 | mapToIterate = new Map();
414 | expect(mapToIterate.set('a', 1)).to.equal(mapToIterate);
415 | expect(mapToIterate.set('b', 2)).to.equal(mapToIterate);
416 | expect(mapToIterate.set('c', 3)).to.equal(mapToIterate);
417 | });
418 |
419 | afterEach(function () {
420 | mapToIterate = null;
421 | });
422 |
423 | ifFunctionsHaveNamesIt('has the right name', function () {
424 | expect(Map.prototype.forEach).to.have.property('name', 'forEach');
425 | });
426 |
427 | it('is not enumerable', function () {
428 | expect(Map.prototype).ownPropertyDescriptor('forEach').to.have.property('enumerable', false);
429 | });
430 |
431 | it('has the right arity', function () {
432 | expect(Map.prototype.forEach).to.have.property('length', 1);
433 | });
434 |
435 | it('should be iterable via forEach', function () {
436 | var expectedMap = {
437 | a: 1,
438 | b: 2,
439 | c: 3
440 | };
441 | var foundMap = {};
442 | mapToIterate.forEach(function (value, key, entireMap) {
443 | expect(entireMap).to.equal(mapToIterate);
444 | foundMap[key] = value;
445 | });
446 | expect(foundMap).to.eql(expectedMap);
447 | });
448 |
449 | it('should iterate over empty keys', function () {
450 | var mapWithEmptyKeys = new Map();
451 | var expectedKeys = [{}, null, undefined, '', NaN, 0];
452 | expectedKeys.forEach(function (key) {
453 | expect(mapWithEmptyKeys.set(key, true)).to.equal(mapWithEmptyKeys);
454 | });
455 | var foundKeys = [];
456 | mapWithEmptyKeys.forEach(function (value, key, entireMap) {
457 | expect(entireMap.get(key)).to.equal(value);
458 | foundKeys.push(key);
459 | });
460 | expect(foundKeys).to.be.theSameSet(expectedKeys);
461 | });
462 |
463 | it('should support the thisArg', function () {
464 | var context = function () {};
465 | mapToIterate.forEach(function () {
466 | expect(this).to.equal(context);
467 | }, context);
468 | });
469 |
470 | it('should have a length of 1', function () {
471 | expect(Map.prototype.forEach.length).to.equal(1);
472 | });
473 |
474 | it('should not revisit modified keys', function () {
475 | var hasModifiedA = false;
476 | mapToIterate.forEach(function (value, key) {
477 | if (!hasModifiedA && key === 'a') {
478 | expect(mapToIterate.set('a', 4)).to.equal(mapToIterate);
479 | hasModifiedA = true;
480 | } else {
481 | expect(key).not.to.equal('a');
482 | }
483 | });
484 | });
485 |
486 | it('returns the map from #set() for chaining', function () {
487 | expect(mapToIterate.set({}, {})).to.equal(mapToIterate);
488 | expect(mapToIterate.set(42, {})).to.equal(mapToIterate);
489 | expect(mapToIterate.set(0, {})).to.equal(mapToIterate);
490 | expect(mapToIterate.set(NaN, {})).to.equal(mapToIterate);
491 | expect(mapToIterate.set(-0, {})).to.equal(mapToIterate);
492 | });
493 |
494 | it('visits keys added in the iterator', function () {
495 | var hasAdded = false;
496 | var hasFoundD = false;
497 | mapToIterate.forEach(function (value, key) {
498 | if (!hasAdded) {
499 | mapToIterate.set('d', 5);
500 | hasAdded = true;
501 | } else if (key === 'd') {
502 | hasFoundD = true;
503 | }
504 | });
505 | expect(hasFoundD).to.equal(true);
506 | });
507 |
508 | it('visits keys added in the iterator when there is a deletion', function () {
509 | var hasSeenFour = false;
510 | var mapToMutate = new Map();
511 | mapToMutate.set('0', 42);
512 | mapToMutate.forEach(function (value, key) {
513 | if (key === '0') {
514 | expect(mapToMutate['delete']('0')).to.equal(true);
515 | mapToMutate.set('4', 'a value');
516 | } else if (key === '4') {
517 | hasSeenFour = true;
518 | }
519 | });
520 | expect(hasSeenFour).to.equal(true);
521 | });
522 |
523 | it('does not visit keys deleted before a visit', function () {
524 | var hasVisitedC = false;
525 | var hasDeletedC = false;
526 | mapToIterate.forEach(function (value, key) {
527 | if (key === 'c') {
528 | hasVisitedC = true;
529 | }
530 | if (!hasVisitedC && !hasDeletedC) {
531 | hasDeletedC = mapToIterate['delete']('c');
532 | expect(hasDeletedC).to.equal(true);
533 | }
534 | });
535 | expect(hasVisitedC).to.equal(false);
536 | });
537 |
538 | it('should work after deletion of the current key', function () {
539 | var expectedMap = {
540 | a: 1,
541 | b: 2,
542 | c: 3
543 | };
544 | var foundMap = {};
545 | mapToIterate.forEach(function (value, key) {
546 | foundMap[key] = value;
547 | expect(mapToIterate['delete'](key)).to.equal(true);
548 | });
549 | expect(foundMap).to.eql(expectedMap);
550 | });
551 |
552 | it('should convert key -0 to +0', function () {
553 | var zeroMap = new Map();
554 | var result = [];
555 | zeroMap.set(-0, 'a');
556 | zeroMap.forEach(function (value, key) {
557 | result.push(String(1 / key) + ' ' + value);
558 | });
559 | zeroMap.set(1, 'b');
560 | zeroMap.set(0, 'c'); // shouldn't cause reordering
561 | zeroMap.forEach(function (value, key) {
562 | result.push(String(1 / key) + ' ' + value);
563 | });
564 | expect(result.join(', ')).to.equal('Infinity a, Infinity c, 1 b');
565 | });
566 | });
567 |
568 | it('should preserve insertion order', function () {
569 | var convertToPairs = function (item) { return [item, true]; };
570 | var arr1 = ['d', 'a', 'b'];
571 | var arr2 = [3, 2, 'z', 'a', 1];
572 | var arr3 = [3, 2, 'z', {}, 'a', 1];
573 |
574 | [arr1, arr2, arr3].forEach(function (array) {
575 | var entries = array.map(convertToPairs);
576 | expect(new Map(entries)).to.have.entries(entries);
577 | });
578 | });
579 |
580 | it('map iteration', function () {
581 | var map = new Map();
582 | map.set('a', 1);
583 | map.set('b', 2);
584 | map.set('c', 3);
585 | map.set('d', 4);
586 |
587 | var keys = [];
588 | var iterator = map.keys();
589 | keys.push(iterator.next().value);
590 | expect(map['delete']('a')).to.equal(true);
591 | expect(map['delete']('b')).to.equal(true);
592 | expect(map['delete']('c')).to.equal(true);
593 | map.set('e');
594 | keys.push(iterator.next().value);
595 | keys.push(iterator.next().value);
596 |
597 | expect(iterator.next().done).to.equal(true);
598 | map.set('f');
599 | expect(iterator.next().done).to.equal(true);
600 | expect(keys).to.eql(['a', 'd', 'e']);
601 | });
602 |
603 | ifGetPrototypeOfIt('MapIterator identification test prototype inequality', function () {
604 | var mapEntriesProto = Object.getPrototypeOf(new Map().entries());
605 | var setEntriesProto = Object.getPrototypeOf(new Set().entries());
606 | expect(mapEntriesProto).to.not.equal(setEntriesProto);
607 | });
608 |
609 | it('MapIterator identification', function () {
610 | var fnMapValues = Map.prototype.values;
611 | var mapSentinel = new Map([[1, 'MapSentinel']]);
612 | var testMap = new Map();
613 | var testMapValues = testMap.values();
614 | expect(testMapValues.next.call(fnMapValues.call(mapSentinel)).value).to.equal('MapSentinel');
615 |
616 | var testSet = new Set();
617 | var testSetValues = testSet.values();
618 | expect(function () {
619 | return testSetValues.next.call(fnMapValues.call(mapSentinel)).value;
620 | }).to['throw'](TypeError);
621 | });
622 | });
623 |
--------------------------------------------------------------------------------
/test/mocha.opts:
--------------------------------------------------------------------------------
1 | --require es5-shim
2 | --require ./es6-shim
3 | --require ./es6-sham
4 | --require test/test_helpers.js
5 |
6 |
--------------------------------------------------------------------------------
/test/native.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | es6-shim tests
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/test/number.js:
--------------------------------------------------------------------------------
1 | describe('Number', function () {
2 | var functionsHaveNames = (function foo() {}).name === 'foo';
3 | var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
4 | var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
5 |
6 | var integers = [5295, -5295, -9007199254740991, 9007199254740991, 0, -0];
7 | var nonIntegers = [-9007199254741992, 9007199254741992, 5.9];
8 | var infinities = [Infinity, -Infinity];
9 |
10 | var valueOfThree = { valueOf: function () { return 3; } };
11 | var valueOfNaN = { valueOf: function () { return NaN; } };
12 | var valueOfThrows = { valueOf: function () { throw Object(17); } };
13 | var toStringThrows = { toString: function () { throw Object(42); } };
14 | var toPrimitiveThrows = {
15 | valueOf: function () { throw Object(17); },
16 | toString: function () { throw Object(42); }
17 | };
18 |
19 | var nonNumbers = [
20 | undefined,
21 | true,
22 | false,
23 | null,
24 | {},
25 | [],
26 | 'str',
27 | '',
28 | valueOfThree,
29 | valueOfNaN,
30 | valueOfThrows,
31 | toStringThrows,
32 | toPrimitiveThrows,
33 | /a/g
34 | ];
35 | var expectTrue = function (item) {
36 | expect(item).to.equal(true);
37 | };
38 | var expectFalse = function (item) {
39 | expect(item).to.equal(false);
40 | };
41 |
42 | ifShimIt('is on the exported object', function () {
43 | var exported = require('../');
44 | expect(exported.Number).to.equal(Number);
45 | });
46 |
47 | describe('Number constants', function () {
48 | it('should have max safe integer', function () {
49 | expect(Number).to.have.property('MAX_SAFE_INTEGER');
50 | expect(Object.prototype.propertyIsEnumerable.call(Number, 'MAX_SAFE_INTEGER')).to.equal(false);
51 | expect(Number.MAX_SAFE_INTEGER).to.equal(Math.pow(2, 53) - 1);
52 | });
53 |
54 | it('should have min safe integer', function () {
55 | expect(Number).to.have.property('MIN_SAFE_INTEGER');
56 | expect(Object.prototype.propertyIsEnumerable.call(Number, 'MIN_SAFE_INTEGER')).to.equal(false);
57 | expect(Number.MIN_SAFE_INTEGER).to.equal(-Math.pow(2, 53) + 1);
58 | });
59 |
60 | it('should have epsilon', function () {
61 | expect(Number).to.have.property('EPSILON');
62 | expect(Object.prototype.propertyIsEnumerable.call(Number, 'EPSILON')).to.equal(false);
63 | expect(Number.EPSILON).to.equal(2.2204460492503130808472633361816e-16);
64 | });
65 |
66 | it('should have NaN', function () {
67 | expect(Number).to.have.property('NaN');
68 | expect(Object.prototype.propertyIsEnumerable.call(Number, 'NaN')).to.equal(false);
69 | expect(isNaN(Number.NaN)).to.equal(true);
70 | });
71 |
72 | it('should have MAX_VALUE', function () {
73 | expect(Number).to.have.property('MAX_VALUE');
74 | expect(Object.prototype.propertyIsEnumerable.call(Number, 'MAX_VALUE')).to.equal(false);
75 | expect(Number.MAX_VALUE).to.equal(1.7976931348623157e+308);
76 | });
77 |
78 | it('should have MIN_VALUE', function () {
79 | expect(Number).to.have.property('MIN_VALUE');
80 | expect(Object.prototype.propertyIsEnumerable.call(Number, 'MIN_VALUE')).to.equal(false);
81 | expect(Number.MIN_VALUE).to.equal(5e-324);
82 | });
83 |
84 | it('should have NEGATIVE_INFINITY', function () {
85 | expect(Number).to.have.property('NEGATIVE_INFINITY');
86 | expect(Object.prototype.propertyIsEnumerable.call(Number, 'NEGATIVE_INFINITY')).to.equal(false);
87 | expect(Number.NEGATIVE_INFINITY).to.equal(-Infinity);
88 | });
89 |
90 | it('should have POSITIVE_INFINITY', function () {
91 | expect(Number).to.have.property('POSITIVE_INFINITY');
92 | expect(Object.prototype.propertyIsEnumerable.call(Number, 'POSITIVE_INFINITY')).to.equal(false);
93 | expect(Number.POSITIVE_INFINITY).to.equal(Infinity);
94 | });
95 | });
96 |
97 | describe('.parseInt()', function () {
98 | if (!Object.prototype.hasOwnProperty.call(Number, 'parseInt')) {
99 | return it('exists', function () {
100 | expect(Number).to.have.property('parseInt');
101 | });
102 | }
103 |
104 | it('should work', function () {
105 | /* eslint-disable radix */
106 | expect(Number.parseInt('601')).to.equal(601);
107 | /* eslint-enable radix */
108 | });
109 |
110 | ifFunctionsHaveNamesIt('has the right name', function () {
111 | expect(Number.parseInt).to.have.property('name', 'parseInt');
112 | });
113 |
114 | it('is not enumerable', function () {
115 | expect(Number).ownPropertyDescriptor('parseInt').to.have.property('enumerable', false);
116 | });
117 |
118 | it('has the right arity', function () {
119 | // WebKit nightly had the wrong length; fixed in https://bugs.webkit.org/show_bug.cgi?id=143657
120 | expect(Number.parseInt).to.have.property('length', 2);
121 | });
122 |
123 | it('is the same object as the global parseInt', function () {
124 | // fixed in WebKit nightly in https://bugs.webkit.org/show_bug.cgi?id=143799#add_comment
125 | expect(Number.parseInt).to.equal(parseInt);
126 | });
127 | });
128 |
129 | describe('.parseFloat()', function () {
130 | if (!Object.prototype.hasOwnProperty.call(Number, 'parseFloat')) {
131 | return it('exists', function () {
132 | expect(Number).to.have.property('parseFloat');
133 | });
134 | }
135 |
136 | it('should work', function () {
137 | expect(Number.parseFloat('5.5')).to.equal(5.5);
138 | });
139 |
140 | ifFunctionsHaveNamesIt('has the right name', function () {
141 | expect(Number.parseFloat).to.have.property('name', 'parseFloat');
142 | });
143 |
144 | it('is not enumerable', function () {
145 | expect(Number).ownPropertyDescriptor('parseFloat').to.have.property('enumerable', false);
146 | });
147 |
148 | it('has the right arity', function () {
149 | expect(Number.parseFloat).to.have.property('length', 1);
150 | });
151 | });
152 |
153 | describe('.isFinite()', function () {
154 | if (!Object.prototype.hasOwnProperty.call(Number, 'isFinite')) {
155 | return it('exists', function () {
156 | expect(Number).to.have.property('isFinite');
157 | });
158 | }
159 |
160 | ifFunctionsHaveNamesIt('has the right name', function () {
161 | expect(Number.isFinite).to.have.property('name', 'isFinite');
162 | });
163 |
164 | it('is not enumerable', function () {
165 | expect(Number).ownPropertyDescriptor('isFinite').to.have.property('enumerable', false);
166 | });
167 |
168 | it('has the right arity', function () {
169 | expect(Number.isFinite).to.have.property('length', 1);
170 | });
171 |
172 | it('should work', function () {
173 | integers.map(Number.isFinite).forEach(expectTrue);
174 | infinities.map(Number.isFinite).forEach(expectFalse);
175 | expect(Number.isFinite(Infinity)).to.equal(false);
176 | expect(Number.isFinite(-Infinity)).to.equal(false);
177 | expect(Number.isFinite(NaN)).to.equal(false);
178 | expect(Number.isFinite(4)).to.equal(true);
179 | expect(Number.isFinite(4.5)).to.equal(true);
180 | expect(Number.isFinite('hi')).to.equal(false);
181 | expect(Number.isFinite('1.3')).to.equal(false);
182 | expect(Number.isFinite('51')).to.equal(false);
183 | expect(Number.isFinite(0)).to.equal(true);
184 | expect(Number.isFinite(-0)).to.equal(true);
185 | expect(Number.isFinite(valueOfThree)).to.equal(false);
186 | expect(Number.isFinite(valueOfNaN)).to.equal(false);
187 | expect(Number.isFinite(valueOfThrows)).to.equal(false);
188 | expect(Number.isFinite(toStringThrows)).to.equal(false);
189 | expect(Number.isFinite(toPrimitiveThrows)).to.equal(false);
190 | });
191 |
192 | it('should not be confused by type coercion', function () {
193 | nonNumbers.map(Number.isFinite).forEach(expectFalse);
194 | });
195 | });
196 |
197 | describe('.isInteger()', function () {
198 | if (!Object.prototype.hasOwnProperty.call(Number, 'isInteger')) {
199 | return it('exists', function () {
200 | expect(Number).to.have.property('isInteger');
201 | });
202 | }
203 |
204 | ifFunctionsHaveNamesIt('has the right name', function () {
205 | expect(Number.isInteger).to.have.property('name', 'isInteger');
206 | });
207 |
208 | it('is not enumerable', function () {
209 | expect(Number).ownPropertyDescriptor('isInteger').to.have.property('enumerable', false);
210 | });
211 |
212 | it('has the right arity', function () {
213 | expect(Number.isInteger).to.have.property('length', 1);
214 | });
215 |
216 | it('should be truthy on integers', function () {
217 | integers.map(Number.isInteger).forEach(expectTrue);
218 | expect(Number.isInteger(4)).to.equal(true);
219 | expect(Number.isInteger(4.0)).to.equal(true);
220 | expect(Number.isInteger(1801439850948)).to.equal(true);
221 | });
222 |
223 | it('should be false when the type is not number', function () {
224 | nonNumbers.forEach(function (thing) {
225 | expect(Number.isInteger(thing)).to.equal(false);
226 | });
227 | });
228 |
229 | it('should be false when NaN', function () {
230 | expect(Number.isInteger(NaN)).to.equal(false);
231 | });
232 |
233 | it('should be false when ∞', function () {
234 | expect(Number.isInteger(Infinity)).to.equal(false);
235 | expect(Number.isInteger(-Infinity)).to.equal(false);
236 | });
237 |
238 | it('should be false when number is not integer', function () {
239 | expect(Number.isInteger(3.4)).to.equal(false);
240 | expect(Number.isInteger(-3.4)).to.equal(false);
241 | });
242 |
243 | it('should be true when abs(number) is 2^53 or larger', function () {
244 | expect(Number.isInteger(Math.pow(2, 53))).to.equal(true);
245 | expect(Number.isInteger(Math.pow(2, 54))).to.equal(true);
246 | expect(Number.isInteger(-Math.pow(2, 53))).to.equal(true);
247 | expect(Number.isInteger(-Math.pow(2, 54))).to.equal(true);
248 | });
249 |
250 | it('should be true when abs(number) is less than 2^53', function () {
251 | var safeIntegers = [0, 1, Math.pow(2, 53) - 1];
252 | safeIntegers.forEach(function (integer) {
253 | expect(Number.isInteger(integer)).to.equal(true);
254 | expect(Number.isInteger(-integer)).to.equal(true);
255 | });
256 | });
257 | });
258 |
259 | describe('.isSafeInteger()', function () {
260 | if (!Object.prototype.hasOwnProperty.call(Number, 'isSafeInteger')) {
261 | return it('exists', function () {
262 | expect(Number).to.have.property('isSafeInteger');
263 | });
264 | }
265 |
266 | ifFunctionsHaveNamesIt('has the right name', function () {
267 | expect(Number.isSafeInteger).to.have.property('name', 'isSafeInteger');
268 | });
269 |
270 | it('is not enumerable', function () {
271 | expect(Number).ownPropertyDescriptor('isSafeInteger').to.have.property('enumerable', false);
272 | });
273 |
274 | it('has the right arity', function () {
275 | expect(Number.isSafeInteger).to.have.property('length', 1);
276 | });
277 |
278 | it('should be truthy on integers', function () {
279 | integers.map(Number.isSafeInteger).forEach(expectTrue);
280 | expect(Number.isSafeInteger(4)).to.equal(true);
281 | expect(Number.isSafeInteger(4.0)).to.equal(true);
282 | expect(Number.isSafeInteger(1801439850948)).to.equal(true);
283 | });
284 |
285 | it('should be false when the type is not number', function () {
286 | nonNumbers.forEach(function (thing) {
287 | expect(Number.isSafeInteger(thing)).to.equal(false);
288 | });
289 | });
290 |
291 | it('should be false when NaN', function () {
292 | expect(Number.isSafeInteger(NaN)).to.equal(false);
293 | });
294 |
295 | it('should be false when ∞', function () {
296 | expect(Number.isSafeInteger(Infinity)).to.equal(false);
297 | expect(Number.isSafeInteger(-Infinity)).to.equal(false);
298 | });
299 |
300 | it('should be false when number is not integer', function () {
301 | expect(Number.isSafeInteger(3.4)).to.equal(false);
302 | expect(Number.isSafeInteger(-3.4)).to.equal(false);
303 | });
304 |
305 | it('should be false when abs(number) is 2^53 or larger', function () {
306 | expect(Number.isSafeInteger(Math.pow(2, 53))).to.equal(false);
307 | expect(Number.isSafeInteger(Math.pow(2, 54))).to.equal(false);
308 | expect(Number.isSafeInteger(-Math.pow(2, 53))).to.equal(false);
309 | expect(Number.isSafeInteger(-Math.pow(2, 54))).to.equal(false);
310 | });
311 |
312 | it('should be true when abs(number) is less than 2^53', function () {
313 | var safeIntegers = [0, 1, Math.pow(2, 53) - 1];
314 | safeIntegers.forEach(function (integer) {
315 | expect(Number.isSafeInteger(integer)).to.equal(true);
316 | expect(Number.isSafeInteger(-integer)).to.equal(true);
317 | });
318 | });
319 | });
320 |
321 | describe('.isNaN()', function () {
322 | if (!Object.prototype.hasOwnProperty.call(Number, 'isNaN')) {
323 | return it('exists', function () {
324 | expect(Number).to.have.property('isNaN');
325 | });
326 | }
327 |
328 | ifFunctionsHaveNamesIt('has the right name', function () {
329 | expect(Number.isNaN).to.have.property('name', 'isNaN');
330 | });
331 |
332 | it('is not enumerable', function () {
333 | expect(Number).ownPropertyDescriptor('isNaN').to.have.property('enumerable', false);
334 | });
335 |
336 | it('has the right arity', function () {
337 | expect(Number.isNaN).to.have.property('length', 1);
338 | });
339 |
340 | it('should be truthy only on NaN', function () {
341 | integers.concat(nonIntegers).map(Number.isNaN).forEach(expectFalse);
342 | nonNumbers.map(Number.isNaN).forEach(expectFalse);
343 | expect(Number.isNaN(NaN)).to.equal(true);
344 | expect(Number.isNaN(0 / 0)).to.equal(true);
345 | expect(Number.isNaN(Number('NaN'))).to.equal(true);
346 | expect(Number.isNaN(4)).to.equal(false);
347 | expect(Number.isNaN(4.5)).to.equal(false);
348 | expect(Number.isNaN('hi')).to.equal(false);
349 | expect(Number.isNaN('1.3')).to.equal(false);
350 | expect(Number.isNaN('51')).to.equal(false);
351 | expect(Number.isNaN(0)).to.equal(false);
352 | expect(Number.isNaN(-0)).to.equal(false);
353 | expect(Number.isNaN(valueOfThree)).to.equal(false);
354 | expect(Number.isNaN(valueOfNaN)).to.equal(false);
355 | expect(Number.isNaN(valueOfThrows)).to.equal(false);
356 | expect(Number.isNaN(toStringThrows)).to.equal(false);
357 | expect(Number.isNaN(toPrimitiveThrows)).to.equal(false);
358 | });
359 | });
360 |
361 | describe('constructor', function () {
362 | it('behaves like the builtin', function () {
363 | expect((1).constructor).to.equal(Number);
364 | expect(Number()).to.equal(0);
365 | });
366 |
367 | describe('strings in the constructor', function () {
368 | it('works on normal literals', function () {
369 | expect(Number('1')).to.equal(+'1');
370 | expect(Number('1.1')).to.equal(+'1.1');
371 | expect(Number('0xA')).to.equal(0xA);
372 | });
373 | });
374 |
375 | describe('when called with a receiver', function () {
376 | it('returns a primitive when called with a primitive receiver', function () {
377 | expect((1).constructor(2)).to.equal(2);
378 | expect((1).constructor.call(null, 3)).to.equal(3);
379 | expect(Object(1).constructor.call(null, 5)).to.equal(5);
380 | });
381 |
382 | it('returns a primitive when called with a different number as an object receiver', function () {
383 | expect(Object(1).constructor(6)).to.equal(6);
384 | expect(Object(1).constructor.call(Object(1), 7)).to.equal(7);
385 | });
386 |
387 | it('returns a primitive when called with the same number as an object receiver', function () {
388 | expect(Object(1).constructor.call(Object(8), 8)).to.equal(8);
389 | });
390 | });
391 |
392 | it('works with boxed primitives', function () {
393 | expect(1 instanceof Number).to.equal(false);
394 | expect(Object(1) instanceof Number).to.equal(true);
395 | });
396 |
397 | it('works with `new`', function () {
398 | /* eslint-disable no-new-wrappers */
399 | var one = new Number('1');
400 | var a = new Number('0xA');
401 | /* eslint-enable no-new-wrappers */
402 |
403 | expect(+one).to.equal(1);
404 | expect(one instanceof Number).to.equal(true);
405 | expect(+a).to.equal(0xA);
406 | expect(a instanceof Number).to.equal(true);
407 | });
408 |
409 | it('works with binary literals in string form', function () {
410 | expect(Number('0b1')).to.equal(1);
411 | expect(Number(' 0b1')).to.equal(1);
412 | expect(Number('0b1 ')).to.equal(1);
413 |
414 | expect(Number('0b10')).to.equal(2);
415 | expect(Number(' 0b10')).to.equal(2);
416 | expect(Number('0b10 ')).to.equal(2);
417 |
418 | expect(Number('0b11')).to.equal(3);
419 | expect(Number(' 0b11')).to.equal(3);
420 | expect(Number('0b11 ')).to.equal(3);
421 |
422 | expect(Number({
423 | toString: function () { return '0b100'; },
424 | valueOf: function () { return '0b101'; }
425 | })).to.equal(5);
426 | });
427 |
428 | it('works with octal literals in string form', function () {
429 | expect(Number('0o7')).to.equal(7);
430 | expect(Number('0o10')).to.equal(8);
431 | expect(Number('0o11')).to.equal(9);
432 | expect(Number({
433 | toString: function () { return '0o12'; },
434 | valueOf: function () { return '0o13'; }
435 | })).to.equal(11);
436 | });
437 |
438 | it('should produce NaN', function () {
439 | expect(String(Number('0b12'))).to.equal('NaN');
440 | expect(String(Number('0o18'))).to.equal('NaN');
441 | expect(String(Number('0x1g'))).to.equal('NaN');
442 | expect(String(Number('+0b1'))).to.equal('NaN');
443 | expect(String(Number('+0o1'))).to.equal('NaN');
444 | expect(String(Number('+0x1'))).to.equal('NaN');
445 | expect(String(Number('-0b1'))).to.equal('NaN');
446 | expect(String(Number('-0o1'))).to.equal('NaN');
447 | expect(String(Number('-0x1'))).to.equal('NaN');
448 | });
449 |
450 | it('should work with well formed and poorly formed objects', function () {
451 | expect(String(Number({}))).to.equal('NaN');
452 | expect(String(Number({ valueOf: '1.1' }))).to.equal('NaN');
453 | expect(Number({ valueOf: '1.1', toString: function () { return '2.2'; } })).to.equal(2.2);
454 | expect(Number({ valueOf: function () { return '1.1'; }, toString: '2.2' })).to.equal(1.1);
455 | expect(Number({
456 | valueOf: function () { return '1.1'; },
457 | toString: function () { return '2.2'; }
458 | })).to.equal(1.1);
459 | expect(String(Number({ valueOf: function () { return '-0x1a2b3c'; } }))).to.equal('NaN');
460 | expect(String(Number({ toString: function () { return '-0x1a2b3c'; } }))).to.equal('NaN');
461 | expect(Number({ valueOf: function () { return '0o12345'; } })).to.equal(5349);
462 | expect(Number({ toString: function () { return '0o12345'; } })).to.equal(5349);
463 | expect(Number({ valueOf: function () { return '0b101010'; } })).to.equal(42);
464 | expect(Number({ toString: function () { return '0b101010'; } })).to.equal(42);
465 | });
466 |
467 | it('should work with correct whitespaces', function () {
468 | // Zero-width space (zws), next line character (nel), and non-character (bom) are not whitespace.
469 | var nonWhitespaces = ['\u0085', '\u200b', '\ufffe'];
470 |
471 | expect(String(Number(nonWhitespaces[0] + '0' + nonWhitespaces[0]))).to.equal('NaN');
472 | expect(String(Number(nonWhitespaces[1] + '1' + nonWhitespaces[1]))).to.equal('NaN');
473 | expect(String(Number(nonWhitespaces[2] + '2' + nonWhitespaces[2]))).to.equal('NaN');
474 | });
475 |
476 | it.skip('it works with updated unicode values', function () {
477 | var whitespace = ' \t\x0b\f\xa0\ufeff\n\r\u2028\u2029\u1680\u180e\u2000\u2001\u2002\u2003\u2004\u2005\u2006\u2007\u2008\u2009\u200a\u202f\u205f\u3000';
478 |
479 | expect(String(Number(whitespace + '3' + whitespace))).to.equal('3');
480 | });
481 | });
482 | });
483 |
--------------------------------------------------------------------------------
/test/object.js:
--------------------------------------------------------------------------------
1 | describe('Object', function () {
2 | var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
3 |
4 | ifShimIt('is on the exported object', function () {
5 | var exported = require('../');
6 | expect(exported.Object).to.equal(Object);
7 | });
8 |
9 | var functionsHaveNames = (function foo() {}).name === 'foo';
10 | var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
11 | var ifExtensionsPreventable = Object.preventExtensions ? it : xit;
12 |
13 | var hasSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol';
14 | var ifSymbolsIt = hasSymbols ? it : xit;
15 | var ifBrowserIt = typeof window === 'object' && typeof document === 'object' ? it : xit;
16 | var ifObjectGetPrototypeOfIt = typeof Object.getPrototypeOf === 'function' ? it : xit;
17 |
18 | if (Object.getOwnPropertyNames) {
19 | describe('.getOwnPropertyNames()', function () {
20 | it('throws on null or undefined', function () {
21 | expect(function () { Object.getOwnPropertyNames(); }).to['throw'](TypeError);
22 | expect(function () { Object.getOwnPropertyNames(undefined); }).to['throw'](TypeError);
23 | expect(function () { Object.getOwnPropertyNames(null); }).to['throw'](TypeError);
24 | });
25 |
26 | it('works on primitives', function () {
27 | [true, false, NaN, 42, /a/g, 'foo'].forEach(function (item) {
28 | expect(Object.getOwnPropertyNames(item)).to.eql(Object.getOwnPropertyNames(Object(item)));
29 | });
30 | });
31 |
32 | ifBrowserIt('does not break when an iframe is added', function () {
33 | var div = document.createElement('div');
34 | div.innerHTML = '';
35 | document.body.appendChild(div);
36 | setTimeout(function () {
37 | document.body.removeChild(div);
38 | }, 0);
39 | expect(Array.isArray(Object.getOwnPropertyNames(window))).to.eql(true);
40 | });
41 | });
42 | }
43 |
44 | if (Object.getOwnPropertyDescriptor) {
45 | describe('.getOwnPropertyDescriptor()', function () {
46 | it('throws on null or undefined', function () {
47 | expect(function () { Object.getOwnPropertyDescriptor(); }).to['throw'](TypeError);
48 | expect(function () { Object.getOwnPropertyDescriptor(undefined); }).to['throw'](TypeError);
49 | expect(function () { Object.getOwnPropertyDescriptor(null); }).to['throw'](TypeError);
50 | });
51 |
52 | it('works on primitives', function () {
53 | [true, false, NaN, 42, /a/g, 'foo'].forEach(function (item) {
54 | expect(Object.getOwnPropertyDescriptor(item, 'foo')).to.eql(Object.getOwnPropertyDescriptor(Object(item), 'foo'));
55 | });
56 | });
57 | });
58 | }
59 |
60 | if (Object.seal) {
61 | describe('.seal()', function () {
62 | it('works on primitives', function () {
63 | [null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
64 | expect(Object.seal(item)).to.eql(item);
65 | });
66 | });
67 | });
68 | }
69 |
70 | if (Object.isSealed) {
71 | describe('.isSealed()', function () {
72 | it('works on primitives', function () {
73 | [null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
74 | expect(Object.isSealed(item)).to.equal(true);
75 | });
76 | });
77 | });
78 | }
79 |
80 | if (Object.freeze) {
81 | describe('.freeze()', function () {
82 | it('works on primitives', function () {
83 | [null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
84 | expect(Object.freeze(item)).to.eql(item);
85 | });
86 | });
87 | });
88 | }
89 |
90 | if (Object.isFrozen) {
91 | describe('.isFrozen()', function () {
92 | it('works on primitives', function () {
93 | [null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
94 | expect(Object.isFrozen(item)).to.equal(true);
95 | });
96 | });
97 | });
98 | }
99 |
100 | if (Object.preventExtensions) {
101 | describe('.preventExtensions()', function () {
102 | it('works on primitives', function () {
103 | [null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
104 | expect(Object.preventExtensions(item)).to.eql(item);
105 | });
106 | });
107 | });
108 | }
109 |
110 | if (Object.isExtensible) {
111 | describe('.isExtensible()', function () {
112 | it('works on primitives', function () {
113 | [null, undefined, true, false, NaN, 42, 'foo'].forEach(function (item) {
114 | expect(Object.isExtensible(item)).to.equal(false);
115 | });
116 | });
117 | });
118 | }
119 |
120 | describe('.keys()', function () {
121 | it('works on strings', function () {
122 | expect(Object.keys('foo')).to.eql(['0', '1', '2']);
123 | });
124 |
125 | it('throws on null or undefined', function () {
126 | expect(function () { Object.keys(); }).to['throw'](TypeError);
127 | expect(function () { Object.keys(undefined); }).to['throw'](TypeError);
128 | expect(function () { Object.keys(null); }).to['throw'](TypeError);
129 | });
130 |
131 | it('works on other primitives', function () {
132 | [true, false, NaN, 42, /a/g].forEach(function (item) {
133 | expect(Object.keys(item)).to.eql([]);
134 | });
135 | });
136 | });
137 |
138 | describe('.is()', function () {
139 | if (!Object.prototype.hasOwnProperty.call(Object, 'is')) {
140 | return it('exists', function () {
141 | expect(Object).to.have.property('is');
142 | });
143 | }
144 |
145 | ifFunctionsHaveNamesIt('has the right name', function () {
146 | expect(Object.is).to.have.property('name', 'is');
147 | });
148 |
149 | it('should have the right arity', function () {
150 | expect(Object.is).to.have.property('length', 2);
151 | });
152 |
153 | it('should compare regular objects correctly', function () {
154 | [null, undefined, [0], 5, 'str', { a: null }].map(function (item) {
155 | return Object.is(item, item);
156 | }).forEach(function (result) {
157 | expect(result).to.equal(true);
158 | });
159 | });
160 |
161 | it('should compare 0 and -0 correctly', function () {
162 | expect(Object.is(0, -0)).to.equal(false);
163 | });
164 |
165 | it('should compare NaNs correctly', function () {
166 | expect(Object.is(NaN, NaN)).to.equal(true);
167 | });
168 | });
169 |
170 | describe('.assign()', function () {
171 | if (!Object.prototype.hasOwnProperty.call(Object, 'assign')) {
172 | return it('exists', function () {
173 | expect(Object).to.have.property('assign');
174 | });
175 | }
176 |
177 | it('has the correct length', function () {
178 | expect(Object.assign.length).to.eql(2);
179 | });
180 |
181 | it('returns the modified target object', function () {
182 | var target = {};
183 | var returned = Object.assign(target, { a: 1 });
184 | expect(returned).to.equal(target);
185 | });
186 |
187 | it('should merge two objects', function () {
188 | var target = { a: 1 };
189 | var returned = Object.assign(target, { b: 2 });
190 | expect(returned).to.eql({ a: 1, b: 2 });
191 | });
192 |
193 | it('should merge three objects', function () {
194 | var target = { a: 1 };
195 | var source1 = { b: 2 };
196 | var source2 = { c: 3 };
197 | var returned = Object.assign(target, source1, source2);
198 | expect(returned).to.eql({ a: 1, b: 2, c: 3 });
199 | });
200 |
201 | it('only iterates over own keys', function () {
202 | var Foo = function () {};
203 | Foo.prototype.bar = true;
204 | var foo = new Foo();
205 | foo.baz = true;
206 | var target = { a: 1 };
207 | var returned = Object.assign(target, foo);
208 | expect(returned).to.equal(target);
209 | expect(target).to.eql({ baz: true, a: 1 });
210 | });
211 |
212 | it('throws when target is null or undefined', function () {
213 | expect(function () { Object.assign(null); }).to['throw'](TypeError);
214 | expect(function () { Object.assign(undefined); }).to['throw'](TypeError);
215 | });
216 |
217 | it('coerces lone target to an object', function () {
218 | var result = {
219 | bool: Object.assign(true),
220 | number: Object.assign(1),
221 | string: Object.assign('1')
222 | };
223 |
224 | expect(typeof result.bool).to.equal('object');
225 | expect(Boolean.prototype.valueOf.call(result.bool)).to.equal(true);
226 |
227 | expect(typeof result.number).to.equal('object');
228 | expect(Number.prototype.valueOf.call(result.number)).to.equal(1);
229 |
230 | expect(typeof result.string).to.equal('object');
231 | expect(String.prototype.valueOf.call(result.string)).to.equal('1');
232 | });
233 |
234 | it('coerces target to an object, assigns from sources', function () {
235 | var sourceA = { a: 1 };
236 | var sourceB = { b: 1 };
237 |
238 | var result = {
239 | bool: Object.assign(true, sourceA, sourceB),
240 | number: Object.assign(1, sourceA, sourceB),
241 | string: Object.assign('1', sourceA, sourceB)
242 | };
243 |
244 | expect(typeof result.bool).to.equal('object');
245 | expect(Boolean.prototype.valueOf.call(result.bool)).to.equal(true);
246 | expect(result.bool).to.eql({ a: 1, b: 1 });
247 |
248 | expect(typeof result.number).to.equal('object');
249 | expect(Number.prototype.valueOf.call(result.number)).to.equal(1);
250 |
251 | expect(typeof result.string).to.equal('object');
252 | expect(String.prototype.valueOf.call(result.string)).to.equal('1');
253 | expect(result.string).to.eql({ 0: '1', a: 1, b: 1 });
254 | });
255 |
256 | it('ignores non-object sources', function () {
257 | expect(Object.assign({ a: 1 }, null, { b: 2 })).to.eql({ a: 1, b: 2 });
258 | expect(Object.assign({ a: 1 }, undefined, { b: 2 })).to.eql({ a: 1, b: 2 });
259 | expect(Object.assign({ a: 1 }, { b: 2 }, null)).to.eql({ a: 1, b: 2 });
260 | });
261 |
262 | ifExtensionsPreventable('does not have pending exceptions', function () {
263 | 'use strict';
264 |
265 | // Firefox 37 still has "pending exception" logic in its Object.assign implementation,
266 | // which is 72% slower than our shim, and Firefox 40's native implementation.
267 | var thrower = { 1: 2, 2: 3, 3: 4 };
268 | Object.defineProperty(thrower, 2, {
269 | get: function () { return 3; },
270 | set: function (v) { throw new RangeError('IE 9 does not throw on preventExtensions: ' + v); }
271 | });
272 | Object.preventExtensions(thrower);
273 | expect(thrower).to.have.property(2, 3);
274 | var error;
275 | try {
276 | Object.assign(thrower, 'wxyz');
277 | } catch (e) {
278 | error = e;
279 | }
280 | expect(thrower).not.to.have.property(0);
281 | if (thrower[1] === 'x') {
282 | // IE 9 doesn't throw in strict mode with preventExtensions
283 | expect(error).to.be.an.instanceOf(RangeError);
284 | } else {
285 | expect(error).to.be.an.instanceOf(TypeError);
286 | expect(thrower).to.have.property(1, 2);
287 | }
288 | expect(thrower).to.have.property(2, 3);
289 | expect(thrower).to.have.property(3, 4);
290 | });
291 |
292 | ifSymbolsIt('includes enumerable symbols, after keys', function () {
293 | /* eslint max-statements-per-line: 1 */
294 | var visited = [];
295 | var obj = {};
296 | Object.defineProperty(obj, 'a', { get: function () { visited.push('a'); return 42; }, enumerable: true });
297 | var symbol = Symbol('enumerable');
298 | Object.defineProperty(obj, symbol, {
299 | get: function () { visited.push(symbol); return Infinity; },
300 | enumerable: true
301 | });
302 | var nonEnumSymbol = Symbol('non-enumerable');
303 | Object.defineProperty(obj, nonEnumSymbol, {
304 | get: function () { visited.push(nonEnumSymbol); return -Infinity; },
305 | enumerable: false
306 | });
307 | var target = Object.assign({}, obj);
308 | expect(visited).to.eql(['a', symbol]);
309 | expect(target.a).to.equal(42);
310 | expect(target[symbol]).to.equal(Infinity);
311 | expect(target[nonEnumSymbol]).not.to.equal(-Infinity);
312 | });
313 | });
314 |
315 | describe('Object.setPrototypeOf()', function () {
316 | if (!Object.setPrototypeOf) {
317 | return; // IE < 11
318 | }
319 |
320 | describe('argument checking', function () {
321 | it('should throw TypeError if first arg is not object', function () {
322 | var nonObjects = [null, undefined, true, false, 1, 3, 'foo'];
323 | nonObjects.forEach(function (value) {
324 | expect(function () { Object.setPrototypeOf(value); }).to['throw'](TypeError);
325 | });
326 | });
327 |
328 | it('should throw TypeError if second arg is not object or null', function () {
329 | expect(function () { Object.setPrototypeOf({}, null); }).not.to['throw'](TypeError);
330 | var invalidPrototypes = [true, false, 1, 3, 'foo'];
331 | invalidPrototypes.forEach(function (proto) {
332 | expect(function () { Object.setPrototypeOf({}, proto); }).to['throw'](TypeError);
333 | });
334 | });
335 | });
336 |
337 | describe('set prototype', function () {
338 | it('should work', function () {
339 | var Foo = function () {};
340 | var Bar = {};
341 | var foo = new Foo();
342 | expect(Object.getPrototypeOf(foo)).to.equal(Foo.prototype);
343 |
344 | var fooBar = Object.setPrototypeOf(foo, Bar);
345 | expect(fooBar).to.equal(foo);
346 | expect(Object.getPrototypeOf(foo)).to.equal(Bar);
347 | });
348 | it('should be able to set to null', function () {
349 | var Foo = function () {};
350 | var foo = new Foo();
351 |
352 | var fooNull = Object.setPrototypeOf(foo, null);
353 | expect(fooNull).to.equal(foo);
354 | expect(Object.getPrototypeOf(foo)).to.equal(null);
355 | });
356 | });
357 | });
358 |
359 | describe('.getPrototypeOf()', function () {
360 | ifObjectGetPrototypeOfIt('does not throw for a primitive', function () {
361 | expect(Object.getPrototypeOf(3)).to.equal(Number.prototype);
362 | });
363 | });
364 | });
365 |
--------------------------------------------------------------------------------
/test/promise.js:
--------------------------------------------------------------------------------
1 | /* This file is for testing implementation regressions of Promises. */
2 |
3 | describe('Promise', function () {
4 | if (typeof Promise === 'undefined') {
5 | return it('exists', function () {
6 | expect(typeof Promise).to.be('function');
7 | });
8 | }
9 |
10 | var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
11 |
12 | ifShimIt('is on the exported object', function () {
13 | var exported = require('../');
14 | expect(exported.Promise).to.equal(Promise);
15 | });
16 |
17 | it('ignores non-function .then arguments', function () {
18 | expect(function () {
19 | Promise.reject(42).then(null, 5).then(null, function () {});
20 | }).not.to['throw']();
21 | });
22 |
23 | describe('extra methods (bad Chrome!)', function () {
24 | it('does not have accept', function () {
25 | expect(Promise).not.to.have.property('accept');
26 | });
27 |
28 | it('does not have defer', function () {
29 | expect(Promise).not.to.have.property('defer');
30 | });
31 |
32 | it('does not have chain', function () {
33 | expect(Promise.prototype).not.to.have.property('chain');
34 | });
35 | });
36 |
37 | it('requires an object context', function () {
38 | // this fails in Safari 7.1 - 9
39 | expect(function promiseDotCallThree() {
40 | Promise.call(3, function () {});
41 | }).to['throw']();
42 | });
43 | });
44 |
--------------------------------------------------------------------------------
/test/promise/all.js:
--------------------------------------------------------------------------------
1 | var failIfThrows = function (done) {
2 | 'use strict';
3 |
4 | return function (e) {
5 | done(e || new Error());
6 | };
7 | };
8 |
9 | describe('Promise.all', function () {
10 | 'use strict';
11 |
12 | it('should not be enumerable', function () {
13 | expect(Promise).ownPropertyDescriptor('all').to.have.property('enumerable', false);
14 | });
15 |
16 | it('fulfills if passed an empty array', function (done) {
17 | var iterable = [];
18 |
19 | Promise.all(iterable).then(function (value) {
20 | assert(Array.isArray(value));
21 | assert.deepEqual(value, []);
22 | }).then(done, failIfThrows(done));
23 | });
24 |
25 | it('fulfills if passed an empty array-like', function (done) {
26 | var f = function () {
27 | Promise.all(arguments).then(function (value) {
28 | assert(Array.isArray(value));
29 | assert.deepEqual(value, []);
30 | }).then(done, failIfThrows(done));
31 | };
32 | f();
33 | });
34 |
35 | it('fulfills if passed an array of mixed fulfilled promises and values', function (done) {
36 | var iterable = [0, Promise.resolve(1), 2, Promise.resolve(3)];
37 |
38 | Promise.all(iterable).then(function (value) {
39 | assert(Array.isArray(value));
40 | assert.deepEqual(value, [0, 1, 2, 3]);
41 | }).then(done, failIfThrows(done));
42 | });
43 |
44 | it('rejects if any passed promise is rejected', function (done) {
45 | var foreverPending = new Promise(function () { });
46 | var error = new Error('Rejected');
47 | var rejected = Promise.reject(error);
48 |
49 | var iterable = [foreverPending, rejected];
50 |
51 | Promise.all(iterable).then(
52 | function () {
53 | assert(false, 'should never get here');
54 | },
55 | function (reason) {
56 | assert.strictEqual(reason, error);
57 | }
58 | ).then(done, failIfThrows(done));
59 | });
60 |
61 | it('resolves foreign thenables', function (done) {
62 | var normal = Promise.resolve(1);
63 | var foreign = { then: function (f) { f(2); } };
64 |
65 | var iterable = [normal, foreign];
66 |
67 | Promise.all(iterable).then(function (value) {
68 | assert.deepEqual(value, [1, 2]);
69 | }).then(done, failIfThrows(done));
70 | });
71 |
72 | it('fulfills when passed an sparse array, giving `undefined` for the omitted values', function (done) {
73 | /* eslint-disable no-sparse-arrays */
74 | var iterable = [Promise.resolve(0), , , Promise.resolve(1)];
75 | /* eslint-enable no-sparse-arrays */
76 |
77 | Promise.all(iterable).then(function (value) {
78 | assert.deepEqual(value, [0, undefined, undefined, 1]);
79 | }).then(done, failIfThrows(done));
80 | });
81 |
82 | it('does not modify the input array', function (done) {
83 | var input = [0, 1];
84 | var iterable = input;
85 |
86 | Promise.all(iterable).then(function (value) {
87 | assert.notStrictEqual(input, value);
88 | }).then(done, failIfThrows(done));
89 | });
90 |
91 | it('should reject with a TypeError if given a non-iterable', function (done) {
92 | var notIterable = {};
93 |
94 | Promise.all(notIterable).then(
95 | function () {
96 | assert(false, 'should never get here');
97 | },
98 | function (reason) {
99 | assert(reason instanceof TypeError);
100 | }
101 | ).then(done, failIfThrows(done));
102 | });
103 |
104 | // test cases from
105 | // https://github.com/domenic/promises-unwrapping/issues/89#issuecomment-33110203
106 | var tamper = function (p) {
107 | // eslint-disable-next-line no-param-reassign
108 | p.then = function (fulfill, reject) {
109 | fulfill('tampered');
110 | return Promise.prototype.then.call(this, fulfill, reject);
111 | };
112 | return p;
113 | };
114 |
115 | it('should be robust against tampering (1)', function (done) {
116 | var g = [tamper(Promise.resolve(0))];
117 | // Prevent countdownHolder.[[Countdown]] from ever reaching zero
118 | Promise.all(g).then(
119 | function () { done(); },
120 | failIfThrows(done)
121 | );
122 | });
123 |
124 | it('should be robust against tampering (2)', function (done) {
125 | // Promise from Promise.all resolved before arguments
126 | var fulfillCalled = false;
127 |
128 | var g = [
129 | Promise.resolve(0),
130 | tamper(Promise.resolve(1)),
131 | Promise.resolve(2).then(function () {
132 | assert(!fulfillCalled, 'should be resolved before all()');
133 | }).then(function () {
134 | assert(!fulfillCalled, 'should be resolved before all()');
135 | })['catch'](failIfThrows(done))
136 | ];
137 | Promise.all(g).then(function () {
138 | assert(!fulfillCalled, 'should be resolved last');
139 | fulfillCalled = true;
140 | }).then(done, failIfThrows(done));
141 | });
142 |
143 | it('should be robust against tampering (3)', function (done) {
144 | var g = [
145 | Promise.resolve(0),
146 | tamper(Promise.resolve(1)),
147 | Promise.reject(2)
148 | ];
149 | // Promise from Promise.all resolved despite rejected promise in arguments
150 | Promise.all(g).then(function () {
151 | throw new Error('should not reach here!');
152 | }, function (e) {
153 | assert.strictEqual(e, 2);
154 | }).then(done, failIfThrows(done));
155 | });
156 |
157 | it('should be robust against tampering (4)', function (done) {
158 | var hijack = true;
159 | var actualArguments = [];
160 | var P = function (resolver) {
161 | var self;
162 | if (hijack) {
163 | hijack = false;
164 | self = new Promise(function (resolve, reject) {
165 | resolver(function (values) {
166 | // record arguments & # of times resolve function is called
167 | actualArguments.push(values.slice());
168 | return resolve(values);
169 | }, reject);
170 | });
171 | } else {
172 | self = new Promise(resolver);
173 | }
174 | Object.setPrototypeOf(self, P.prototype);
175 | return self;
176 | };
177 | if (!Object.setPrototypeOf) { return done(); } // skip test if on IE < 11
178 | Object.setPrototypeOf(P, Promise);
179 | P.prototype = Object.create(Promise.prototype, {
180 | constructor: { value: P }
181 | });
182 | P.resolve = function (p) { return p; };
183 |
184 | var g = [
185 | Promise.resolve(0),
186 | tamper(Promise.resolve(1)),
187 | Promise.resolve(2)
188 | ];
189 |
190 | // Promise.all calls resolver twice
191 | P.all(g)['catch'](failIfThrows(done));
192 | Promise.resolve().then(function () {
193 | assert.deepEqual(actualArguments, [[0, 'tampered', 2]]);
194 | }).then(done, failIfThrows(done));
195 | });
196 | });
197 |
--------------------------------------------------------------------------------
/test/promise/evil-promises.js:
--------------------------------------------------------------------------------
1 | describe('Evil promises should not be able to break invariants', function () {
2 | 'use strict';
3 |
4 | specify('resolving to a promise that calls onFulfilled twice', function (done) {
5 | // note that we have to create a trivial subclass, as otherwise the
6 | // Promise.resolve(evilPromise) is just the identity function.
7 | // (And in fact, most native Promise implementations use a private
8 | // [[PromiseConstructor]] field in `Promise.resolve` which can't be
9 | // easily patched in an ES5 engine, so instead of
10 | // `Promise.resolve(evilPromise)` we'll use
11 | // `new Promise(function(r){r(evilPromise);})` below.)
12 | var EvilPromise = function (executor) {
13 | var self = new Promise(executor);
14 | Object.setPrototypeOf(self, EvilPromise.prototype);
15 | return self;
16 | };
17 | if (!Object.setPrototypeOf) { return done(); } // skip test if on IE < 11
18 | Object.setPrototypeOf(EvilPromise, Promise);
19 | EvilPromise.prototype = Object.create(Promise.prototype, {
20 | constructor: { value: EvilPromise }
21 | });
22 |
23 | var evilPromise = EvilPromise.resolve();
24 | evilPromise.then = function (f) {
25 | f(1);
26 | f(2);
27 | };
28 |
29 | var calledAlready = false;
30 | new Promise(function (r) { r(evilPromise); }).then(function (value) {
31 | assert.strictEqual(calledAlready, false);
32 | calledAlready = true;
33 | assert.strictEqual(value, 1);
34 | }).then(done, done);
35 | });
36 | });
37 |
--------------------------------------------------------------------------------
/test/promise/promises-aplus.js:
--------------------------------------------------------------------------------
1 | // tests from promises-aplus-tests
2 |
3 | describe('Promises/A+ Tests', function () {
4 | 'use strict';
5 |
6 | if (typeof Promise === 'undefined') {
7 | return;
8 | }
9 |
10 | require('promises-aplus-tests').mocha({
11 | // an adapter from es6 spec to Promises/A+
12 | deferred: function () {
13 | var result = {};
14 | result.promise = new Promise(function (resolve, reject) {
15 | result.resolve = resolve;
16 | result.reject = reject;
17 | });
18 | return result;
19 | },
20 | resolved: Promise.resolve.bind(Promise),
21 | rejected: Promise.reject.bind(Promise)
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/test/promise/promises-es6.js:
--------------------------------------------------------------------------------
1 | // tests from promises-es6-tests
2 | (function () {
3 | 'use strict';
4 |
5 | if (typeof Promise === 'undefined') {
6 | return;
7 | }
8 |
9 | describe('Promises/ES6 Tests', function () {
10 |
11 | // an adapter that sets up global.Promise
12 | // since it's already set up, empty functions will suffice
13 | var adapter = {
14 | defineGlobalPromise: function () {
15 | },
16 | removeGlobalPromise: function () {
17 | }
18 | };
19 |
20 | require('promises-es6-tests').mocha(adapter);
21 | });
22 | }());
23 |
--------------------------------------------------------------------------------
/test/promise/race.js:
--------------------------------------------------------------------------------
1 | var failIfThrows = function (done) {
2 | 'use strict';
3 |
4 | return function (e) {
5 | done(e || new Error());
6 | };
7 | };
8 |
9 | var delayPromise = function (value, ms) {
10 | 'use strict';
11 |
12 | return new Promise(function (resolve) {
13 | setTimeout(function () {
14 | resolve(value);
15 | }, ms);
16 | });
17 | };
18 |
19 | describe('Promise.race', function () {
20 | 'use strict';
21 |
22 | it('should not be enumerable', function () {
23 | expect(Promise).ownPropertyDescriptor('race').to.have.property('enumerable', false);
24 | });
25 |
26 | it('should fulfill if all promises are settled and the ordinally-first is fulfilled', function (done) {
27 | var iterable = [Promise.resolve(1), Promise.reject(2), Promise.resolve(3)];
28 |
29 | Promise.race(iterable).then(function (value) {
30 | assert.strictEqual(value, 1);
31 | }).then(done, failIfThrows(done));
32 | });
33 |
34 | it('should reject if all promises are settled and the ordinally-first is rejected', function (done) {
35 | var iterable = [Promise.reject(1), Promise.reject(2), Promise.resolve(3)];
36 |
37 | Promise.race(iterable).then(
38 | function () {
39 | assert(false, 'should never get here');
40 | },
41 | function (reason) {
42 | assert.strictEqual(reason, 1);
43 | }
44 | ).then(done, failIfThrows(done));
45 | });
46 |
47 | it('should settle in the same way as the first promise to settle', function (done) {
48 | // ensure that even if timeouts are delayed an all execute together,
49 | // p2 will settle first.
50 | var p2 = delayPromise(2, 200);
51 | var p1 = delayPromise(1, 1000);
52 | var p3 = delayPromise(3, 500);
53 | var iterable = [p1, p2, p3];
54 |
55 | Promise.race(iterable).then(function (value) {
56 | assert.strictEqual(value, 2);
57 | }).then(done, failIfThrows(done));
58 | });
59 |
60 | // see https://github.com/domenic/promises-unwrapping/issues/75
61 | it('should never settle when given an empty iterable', function (done) {
62 | var iterable = [];
63 | var settled = false;
64 |
65 | Promise.race(iterable).then(
66 | function () { settled = true; },
67 | function () { settled = true; }
68 | );
69 |
70 | setTimeout(function () {
71 | assert.strictEqual(settled, false);
72 | done();
73 | }, 300);
74 | });
75 |
76 | it('should reject with a TypeError if given a non-iterable', function (done) {
77 | var notIterable = {};
78 |
79 | Promise.race(notIterable).then(
80 | function () {
81 | assert(false, 'should never get here');
82 | },
83 | function (reason) {
84 | assert(reason instanceof TypeError);
85 | }
86 | ).then(done, failIfThrows(done));
87 | });
88 | });
89 |
--------------------------------------------------------------------------------
/test/promise/reject.js:
--------------------------------------------------------------------------------
1 | var failIfThrows = function (done) {
2 | 'use strict';
3 |
4 | return function (e) {
5 | done(e || new Error());
6 | };
7 | };
8 |
9 | describe('Promise.reject', function () {
10 | 'use strict';
11 |
12 | it('should not be enumerable', function () {
13 | expect(Promise).ownPropertyDescriptor('reject').to.have.property('enumerable', false);
14 | });
15 |
16 | it('should return a rejected promise', function (done) {
17 | var value = {};
18 | Promise.reject(value).then(failIfThrows(done), function (result) {
19 | expect(result).to.equal(value);
20 | done();
21 | });
22 | });
23 |
24 | it('throws when receiver is a primitive', function () {
25 | var promise = Promise.reject();
26 | expect(function () { Promise.reject.call(undefined, promise); }).to['throw']();
27 | expect(function () { Promise.reject.call(null, promise); }).to['throw']();
28 | expect(function () { Promise.reject.call('', promise); }).to['throw']();
29 | expect(function () { Promise.reject.call(42, promise); }).to['throw']();
30 | expect(function () { Promise.reject.call(false, promise); }).to['throw']();
31 | expect(function () { Promise.reject.call(true, promise); }).to['throw']();
32 | promise.then(null, function () {}); // silence unhandled rejection errors in Chrome
33 | });
34 | });
35 |
--------------------------------------------------------------------------------
/test/promise/resolve.js:
--------------------------------------------------------------------------------
1 | var failIfThrows = function (done) {
2 | 'use strict';
3 |
4 | return function (e) {
5 | done(e || new Error());
6 | };
7 | };
8 |
9 | describe('Promise.resolve', function () {
10 | 'use strict';
11 |
12 | it('should not be enumerable', function () {
13 | expect(Promise).ownPropertyDescriptor('resolve').to.have.property('enumerable', false);
14 | });
15 |
16 | it('should return a resolved promise', function (done) {
17 | var value = {};
18 | Promise.resolve(value).then(function (result) {
19 | expect(result).to.equal(value);
20 | done();
21 | }, failIfThrows(done));
22 | });
23 |
24 | it('throws when receiver is a primitive', function () {
25 | var promise = Promise.resolve();
26 | expect(function () { Promise.resolve.call(undefined, promise); }).to['throw']();
27 | expect(function () { Promise.resolve.call(null, promise); }).to['throw']();
28 | expect(function () { Promise.resolve.call('', promise); }).to['throw']();
29 | expect(function () { Promise.resolve.call(42, promise); }).to['throw']();
30 | expect(function () { Promise.resolve.call(false, promise); }).to['throw']();
31 | expect(function () { Promise.resolve.call(true, promise); }).to['throw']();
32 | });
33 | });
34 |
--------------------------------------------------------------------------------
/test/promise/simple.js:
--------------------------------------------------------------------------------
1 | var failIfThrows = function (done) {
2 | 'use strict';
3 |
4 | return function (e) {
5 | done(e || new Error());
6 | };
7 | };
8 |
9 | describe('Promise', function () {
10 | 'use strict';
11 |
12 | specify('sanity check: a fulfilled promise calls its fulfillment handler', function (done) {
13 | Promise.resolve(5).then(function (value) {
14 | assert.strictEqual(value, 5);
15 | }).then(done, failIfThrows(done));
16 | });
17 |
18 | specify('directly resolving the promise with itself', function (done) {
19 | var resolvePromise;
20 | var promise = new Promise(function (resolve) { resolvePromise = resolve; });
21 |
22 | resolvePromise(promise);
23 |
24 | promise.then(
25 | function () {
26 | assert(false, 'Should not be fulfilled');
27 | },
28 | function (err) {
29 | assert(err instanceof TypeError);
30 | }
31 | ).then(done, failIfThrows(done));
32 | });
33 |
34 | specify('Stealing a resolver and using it to trigger possible reentrancy bug (#83)', function () {
35 | var stolenResolver;
36 | var StealingPromiseConstructor = function StealingPromiseConstructor(resolver) {
37 | stolenResolver = resolver;
38 | resolver(function () { }, function () { });
39 | };
40 |
41 | var iterable = {};
42 | var atAtIterator = '@@iterator'; // on firefox, at least.
43 | iterable[atAtIterator] = function () {
44 | stolenResolver(null, null);
45 | throw new Error(0);
46 | };
47 |
48 | assert.doesNotThrow(function () {
49 | Promise.all.call(StealingPromiseConstructor, iterable);
50 | });
51 | });
52 |
53 | specify('resolve with a thenable calls it once', function () {
54 | var resolve;
55 | var p = new Promise(function (r) { resolve = r; });
56 | var count = 0;
57 | resolve({
58 | then: function () {
59 | count += 1;
60 | throw new RangeError('reject the promise');
61 | }
62 | });
63 | var a = p.then(function () {})['catch'](function (err) {
64 | assert.equal(count, 1);
65 | assert.ok(err instanceof RangeError);
66 | });
67 | var b = p.then(function () {})['catch'](function (err) {
68 | assert.equal(count, 1);
69 | assert.ok(err instanceof RangeError);
70 | });
71 | return Promise.all([a, b]);
72 | });
73 |
74 | specify('resolve with a thenable that throws on .then, rejects the promise synchronously', function () {
75 | var resolve;
76 | var p = new Promise(function (r) { resolve = r; });
77 | var count = 0;
78 | var thenable = Object.defineProperty({}, 'then', {
79 | get: function () {
80 | count += 1;
81 | throw new RangeError('no then for you');
82 | }
83 | });
84 | resolve(thenable);
85 | assert.equal(count, 1);
86 | var a = p.then(function () {})['catch'](function (err) {
87 | assert.equal(count, 1);
88 | assert.ok(err instanceof RangeError);
89 | });
90 | var b = p.then(function () {})['catch'](function (err) {
91 | assert.equal(count, 1);
92 | assert.ok(err instanceof RangeError);
93 | });
94 | return Promise.all([a, b]);
95 | });
96 | });
97 |
--------------------------------------------------------------------------------
/test/promise/subclass.js:
--------------------------------------------------------------------------------
1 | describe('Support user subclassing of Promise', function () {
2 | 'use strict';
3 |
4 | it('should work if you do it right', function (done) {
5 | // This is the "correct" es6-compatible way.
6 | // (Thanks, @domenic and @zloirock!)
7 | var MyPromise = function (executor) {
8 | var self = new Promise(executor);
9 | Object.setPrototypeOf(self, MyPromise.prototype);
10 | self.mine = 'yeah';
11 | return self;
12 | };
13 | if (!Object.setPrototypeOf) { return done(); } // skip test if on IE < 11
14 | Object.setPrototypeOf(MyPromise, Promise);
15 | MyPromise.prototype = Object.create(Promise.prototype, {
16 | constructor: { value: MyPromise }
17 | });
18 |
19 | // let's try it!
20 | var p1 = MyPromise.resolve(5);
21 | assert.strictEqual(p1.mine, 'yeah');
22 | p1 = p1.then(function (x) {
23 | assert.strictEqual(x, 5);
24 | });
25 | assert.strictEqual(p1.mine, 'yeah');
26 |
27 | var p2 = new MyPromise(function (r) { r(6); });
28 | assert.strictEqual(p2.mine, 'yeah');
29 | p2 = p2.then(function (x) {
30 | assert.strictEqual(x, 6);
31 | });
32 | assert.strictEqual(p2.mine, 'yeah');
33 |
34 | var p3 = MyPromise.all([p1, p2]);
35 | assert.strictEqual(p3.mine, 'yeah');
36 | p3.then(function () { done(); }, done);
37 | });
38 |
39 | it("should throw if you don't inherit at all", function () {
40 | var MyPromise = function () {};
41 | assert['throws'](function () {
42 | Promise.all.call(MyPromise, []);
43 | }, TypeError);
44 | });
45 | });
46 |
--------------------------------------------------------------------------------
/test/reflect.js:
--------------------------------------------------------------------------------
1 | var arePropertyDescriptorsSupported = function () {
2 | try {
3 | Object.defineProperty({}, 'x', {});
4 | return true;
5 | } catch (e) { /* this is IE 8. */
6 | return false;
7 | }
8 | };
9 | var supportsDescriptors = !!Object.defineProperty && arePropertyDescriptorsSupported();
10 | var functionsHaveNames = function f() {}.name === 'f';
11 |
12 | var hasSymbols = typeof Symbol === 'function' && typeof Symbol() === 'symbol';
13 | var ifSymbolsIt = hasSymbols ? it : xit;
14 | var describeIfGetProto = Object.getPrototypeOf ? describe : xdescribe;
15 | var describeIfSetProto = Object.setPrototypeOf ? describe : xdescribe;
16 | var describeIfES5 = supportsDescriptors ? describe : xdescribe;
17 | var describeIfExtensionsPreventible = Object.preventExtensions ? describe : xdescribe;
18 | var describeIfGetOwnPropertyNames = Object.getOwnPropertyNames ? describe : xdescribe;
19 | var ifExtensionsPreventibleIt = Object.preventExtensions ? it : xit;
20 | var ifES5It = supportsDescriptors ? it : xit;
21 | var ifFreezeIt = typeof Object.freeze === 'function' ? it : xit;
22 | var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
23 | var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
24 |
25 | describe('Reflect', function () {
26 | if (typeof Reflect === 'undefined') {
27 | return it('exists', function () {
28 | expect(this).to.have.property('Reflect');
29 | });
30 | }
31 |
32 | var object = {
33 | something: 1,
34 | _value: 0
35 | };
36 |
37 | if (supportsDescriptors) {
38 | /* eslint-disable accessor-pairs */
39 | Object.defineProperties(object, {
40 | value: {
41 | get: function () {
42 | return this._value;
43 | }
44 | },
45 |
46 | setter: {
47 | set: function (val) {
48 | this._value = val;
49 | }
50 | },
51 |
52 | bool: {
53 | value: true
54 | }
55 | });
56 | /* eslint-enable accessor-pairs */
57 | }
58 |
59 | var testXThrow = function (values, func) {
60 | var checker = function checker(item) {
61 | try {
62 | func(item);
63 | return false;
64 | } catch (e) {
65 | return e instanceof TypeError;
66 | }
67 | };
68 |
69 | values.forEach(function (item) {
70 | expect(item).to.satisfy(checker);
71 | });
72 | };
73 |
74 | var testCallableThrow = testXThrow.bind(null, [null, undefined, 1, 'string', true, [], {}]);
75 |
76 | var testPrimitiveThrow = testXThrow.bind(null, [null, undefined, 1, 'string', true]);
77 |
78 | ifShimIt('is on the exported object', function () {
79 | var exported = require('../');
80 | expect(exported.Reflect).to.equal(Reflect);
81 | });
82 |
83 | describe('.apply()', function () {
84 | if (typeof Reflect.apply === 'undefined') {
85 | return it('exists', function () {
86 | expect(Reflect).to.have.property('apply');
87 | });
88 | }
89 |
90 | it('is a function', function () {
91 | expect(typeof Reflect.apply).to.equal('function');
92 | });
93 |
94 | ifFunctionsHaveNamesIt('has the right name', function () {
95 | expect(Reflect.apply.name).to.equal('apply');
96 | });
97 |
98 | it('throws if target isn’t callable', function () {
99 | testCallableThrow(function (item) {
100 | return Reflect.apply(item, null, []);
101 | });
102 | });
103 |
104 | it('works also with redefined apply', function () {
105 | expect(Reflect.apply(Array.prototype.push, [1, 2], [3, 4, 5])).to.equal(5);
106 |
107 | var F = function F(a, b, c) {
108 | return a + b + c;
109 | };
110 |
111 | F.apply = false;
112 |
113 | expect(Reflect.apply(F, null, [1, 2, 3])).to.equal(6);
114 |
115 | var G = function G(last) {
116 | return this.x + 'lo' + last;
117 | };
118 |
119 | G.apply = function nop() {};
120 |
121 | expect(Reflect.apply(G, { x: 'yel' }, ['!'])).to.equal('yello!');
122 | });
123 | });
124 |
125 | describe('.construct()', function () {
126 | if (typeof Reflect.construct === 'undefined') {
127 | return it('exists', function () {
128 | expect(Reflect).to.have.property('construct');
129 | });
130 | }
131 |
132 | it('is a function', function () {
133 | expect(typeof Reflect.construct).to.equal('function');
134 | });
135 |
136 | ifFunctionsHaveNamesIt('has the right name', function () {
137 | expect(Reflect.construct.name).to.equal('construct');
138 | });
139 |
140 | it('throws if target isn’t callable', function () {
141 | testCallableThrow(function (item) {
142 | return Reflect.apply(item, null, []);
143 | });
144 | });
145 |
146 | it('works also with redefined apply', function () {
147 | var C = function C(a, b, c) {
148 | this.qux = [a, b, c].join('|');
149 | };
150 |
151 | C.apply = undefined;
152 |
153 | expect(Reflect.construct(C, ['foo', 'bar', 'baz']).qux).to.equal('foo|bar|baz');
154 | });
155 |
156 | it('correctly handles newTarget param', function () {
157 | var F = function F() {};
158 | expect(Reflect.construct(function () {}, [], F) instanceof F).to.equal(true);
159 | });
160 | });
161 |
162 | describeIfES5('.defineProperty()', function () {
163 | if (typeof Reflect.defineProperty === 'undefined') {
164 | return it('exists', function () {
165 | expect(Reflect).to.have.property('defineProperty');
166 | });
167 | }
168 |
169 | it('is a function', function () {
170 | expect(typeof Reflect.defineProperty).to.equal('function');
171 | });
172 |
173 | ifFunctionsHaveNamesIt('has the right name', function () {
174 | expect(Reflect.defineProperty.name).to.equal('defineProperty');
175 | });
176 |
177 | it('throws if the target isn’t an object', function () {
178 | testPrimitiveThrow(function (item) {
179 | return Reflect.defineProperty(item, 'prop', { value: true });
180 | });
181 | });
182 |
183 | ifExtensionsPreventibleIt('returns false for non-extensible objects', function () {
184 | var o = Object.preventExtensions({});
185 |
186 | expect(Reflect.defineProperty(o, 'prop', {})).to.equal(false);
187 | });
188 |
189 | it('can return true, even for non-configurable, non-writable properties', function () {
190 | var o = {};
191 | var desc = {
192 | value: 13,
193 | enumerable: false,
194 | writable: false,
195 | configurable: false
196 | };
197 |
198 | expect(Reflect.defineProperty(o, 'prop', desc)).to.equal(true);
199 |
200 | // Defined as non-configurable, but descriptor is identical.
201 | expect(Reflect.defineProperty(o, 'prop', desc)).to.equal(true);
202 |
203 | desc.value = 37; // Change
204 |
205 | expect(Reflect.defineProperty(o, 'prop', desc)).to.equal(false);
206 | });
207 |
208 | it('can change from one property type to another, if configurable', function () {
209 | var o = {};
210 |
211 | var desc1 = {
212 | set: function () {},
213 | configurable: true
214 | };
215 |
216 | var desc2 = {
217 | value: 13,
218 | configurable: false
219 | };
220 |
221 | var desc3 = {
222 | get: function () {}
223 | };
224 |
225 | expect(Reflect.defineProperty(o, 'prop', desc1)).to.equal(true);
226 |
227 | expect(Reflect.defineProperty(o, 'prop', desc2)).to.equal(true);
228 |
229 | expect(Reflect.defineProperty(o, 'prop', desc3)).to.equal(false);
230 | });
231 | });
232 |
233 | describe('.deleteProperty()', function () {
234 | if (typeof Reflect.deleteProperty === 'undefined') {
235 | return it('exists', function () {
236 | expect(Reflect).to.have.property('deleteProperty');
237 | });
238 | }
239 |
240 | it('is a function', function () {
241 | expect(typeof Reflect.deleteProperty).to.equal('function');
242 | });
243 |
244 | ifFunctionsHaveNamesIt('has the right name', function () {
245 | expect(Reflect.deleteProperty.name).to.equal('deleteProperty');
246 | });
247 |
248 | it('throws if the target isn’t an object', function () {
249 | testPrimitiveThrow(function (item) {
250 | return Reflect.deleteProperty(item, 'prop');
251 | });
252 | });
253 |
254 | ifES5It('returns true for success and false for failure', function () {
255 | var o = { a: 1 };
256 |
257 | Object.defineProperty(o, 'b', { value: 2 });
258 |
259 | expect(o).to.have.property('a');
260 | expect(o).to.have.property('b');
261 | expect(o.a).to.equal(1);
262 | expect(o.b).to.equal(2);
263 |
264 | expect(Reflect.deleteProperty(o, 'a')).to.equal(true);
265 |
266 | expect(o).not.to.have.property('a');
267 | expect(o.b).to.equal(2);
268 |
269 | expect(Reflect.deleteProperty(o, 'b')).to.equal(false);
270 |
271 | expect(o).to.have.property('b');
272 | expect(o.b).to.equal(2);
273 |
274 | expect(Reflect.deleteProperty(o, 'a')).to.equal(true);
275 | });
276 |
277 | it('cannot delete an array’s length property', function () {
278 | expect(Reflect.deleteProperty([], 'length')).to.equal(false);
279 | });
280 | });
281 |
282 | describeIfES5('.get()', function () {
283 | if (typeof Reflect.get === 'undefined') {
284 | return it('exists', function () {
285 | expect(Reflect).to.have.property('get');
286 | });
287 | }
288 |
289 | it('is a function', function () {
290 | expect(typeof Reflect.get).to.equal('function');
291 | });
292 |
293 | ifFunctionsHaveNamesIt('has the right name', function () {
294 | expect(Reflect.get.name).to.equal('get');
295 | });
296 |
297 | it('throws on null and undefined', function () {
298 | [null, undefined].forEach(function (item) {
299 | expect(function () {
300 | return Reflect.get(item, 'property');
301 | }).to['throw'](TypeError);
302 | });
303 | });
304 |
305 | it('can retrieve a simple value, from the target', function () {
306 | var p = { something: 2, bool: false };
307 |
308 | expect(Reflect.get(object, 'something')).to.equal(1);
309 | // p has no effect
310 | expect(Reflect.get(object, 'something', p)).to.equal(1);
311 |
312 | // Value-defined properties take the target's value,
313 | // and ignore that of the receiver.
314 | expect(Reflect.get(object, 'bool', p)).to.equal(true);
315 |
316 | // Undefined values
317 | expect(Reflect.get(object, 'undefined_property')).to.equal(undefined);
318 | });
319 |
320 | it('will invoke getters on the receiver rather than target', function () {
321 | var other = { _value: 1337 };
322 |
323 | expect(Reflect.get(object, 'value', other)).to.equal(1337);
324 |
325 | // No getter for setter property
326 | expect(Reflect.get(object, 'setter', other)).to.equal(undefined);
327 | });
328 |
329 | it('will search the prototype chain', function () {
330 | var other = Object.create(object);
331 | other._value = 17;
332 |
333 | var yetAnother = { _value: 4711 };
334 |
335 | expect(Reflect.get(other, 'value', yetAnother)).to.equal(4711);
336 |
337 | expect(Reflect.get(other, 'bool', yetAnother)).to.equal(true);
338 | });
339 | });
340 |
341 | describeIfES5('.set()', function () {
342 | if (typeof Reflect.set === 'undefined') {
343 | return it('exists', function () {
344 | expect(Reflect).to.have.property('set');
345 | });
346 | }
347 |
348 | it('is a function', function () {
349 | expect(typeof Reflect.set).to.equal('function');
350 | });
351 |
352 | ifFunctionsHaveNamesIt('has the right name', function () {
353 | expect(Reflect.set.name).to.equal('set');
354 | });
355 |
356 | it('throws if the target isn’t an object', function () {
357 | testPrimitiveThrow(function (item) {
358 | return Reflect.set(item, 'prop', 'value');
359 | });
360 | });
361 |
362 | it('sets values on receiver', function () {
363 | var target = {};
364 | var receiver = {};
365 |
366 | expect(Reflect.set(target, 'foo', 1, receiver)).to.equal(true);
367 |
368 | expect('foo' in target).to.equal(false);
369 | expect(receiver.foo).to.equal(1);
370 |
371 | expect(Reflect.defineProperty(receiver, 'bar', {
372 | value: 0,
373 | writable: true,
374 | enumerable: false,
375 | configurable: true
376 | })).to.equal(true);
377 |
378 | expect(Reflect.set(target, 'bar', 1, receiver)).to.equal(true);
379 | expect(receiver.bar).to.equal(1);
380 | expect(Reflect.getOwnPropertyDescriptor(receiver, 'bar').enumerable).to.equal(false);
381 |
382 | var out;
383 | /* eslint-disable accessor-pairs */
384 | target = Object.create({}, {
385 | o: {
386 | set: function () { out = this; }
387 | }
388 | });
389 | /* eslint-enable accessor-pairs */
390 |
391 | expect(Reflect.set(target, 'o', 17, receiver)).to.equal(true);
392 | expect(out).to.equal(receiver);
393 | });
394 | });
395 |
396 | describeIfES5('.getOwnPropertyDescriptor()', function () {
397 | if (typeof Reflect.getOwnPropertyDescriptor === 'undefined') {
398 | return it('exists', function () {
399 | expect(Reflect).to.have.property('getOwnPropertyDescriptor');
400 | });
401 | }
402 |
403 | it('is a function', function () {
404 | expect(typeof Reflect.getOwnPropertyDescriptor).to.equal('function');
405 | });
406 |
407 | ifFunctionsHaveNamesIt('has the right name', function () {
408 | expect(Reflect.getOwnPropertyDescriptor.name).to.equal('getOwnPropertyDescriptor');
409 | });
410 |
411 | it('throws if the target isn’t an object', function () {
412 | testPrimitiveThrow(function (item) {
413 | return Reflect.getOwnPropertyDescriptor(item, 'prop');
414 | });
415 | });
416 |
417 | it('retrieves property descriptors', function () {
418 | var obj = { a: 4711 };
419 |
420 | var desc = Reflect.getOwnPropertyDescriptor(obj, 'a');
421 |
422 | expect(desc).to.deep.equal({
423 | value: 4711,
424 | configurable: true,
425 | writable: true,
426 | enumerable: true
427 | });
428 | });
429 | });
430 |
431 | describeIfGetProto('.getPrototypeOf()', function () {
432 | if (typeof Reflect.getPrototypeOf === 'undefined') {
433 | return it('exists', function () {
434 | expect(Reflect).to.have.property('getPrototypeOf');
435 | });
436 | }
437 |
438 | it('is a function', function () {
439 | expect(typeof Reflect.getPrototypeOf).to.equal('function');
440 | });
441 |
442 | ifFunctionsHaveNamesIt('has the right name', function () {
443 | expect(Reflect.getPrototypeOf.name).to.equal('getPrototypeOf');
444 | });
445 |
446 | it('throws if the target isn’t an object', function () {
447 | testPrimitiveThrow(function (item) {
448 | return Reflect.getPrototypeOf(item);
449 | });
450 | });
451 |
452 | it('retrieves prototypes', function () {
453 | expect(Reflect.getPrototypeOf(Object.create(null))).to.equal(null);
454 |
455 | expect(Reflect.getPrototypeOf([])).to.equal(Array.prototype);
456 | });
457 | });
458 |
459 | describe('.has()', function () {
460 | if (typeof Reflect.has === 'undefined') {
461 | return it('exists', function () {
462 | expect(Reflect).to.have.property('has');
463 | });
464 | }
465 |
466 | it('is a function', function () {
467 | expect(typeof Reflect.has).to.equal('function');
468 | });
469 |
470 | ifFunctionsHaveNamesIt('has the right name', function () {
471 | expect(Reflect.has.name).to.equal('has');
472 | });
473 |
474 | it('throws if the target isn’t an object', function () {
475 | testPrimitiveThrow(function (item) {
476 | return Reflect.has(item, 'prop');
477 | });
478 | });
479 |
480 | it('will detect own properties', function () {
481 | var target = Object.create ? Object.create(null) : {};
482 |
483 | expect(Reflect.has(target, 'prop')).to.equal(false);
484 |
485 | target.prop = undefined;
486 | expect(Reflect.has(target, 'prop')).to.equal(true);
487 |
488 | delete target.prop;
489 | expect(Reflect.has(target, 'prop')).to.equal(false);
490 |
491 | expect(Reflect.has(Reflect.has, 'length')).to.equal(true);
492 | });
493 |
494 | ifES5It('will detect an own accessor property', function () {
495 | var target = Object.create(null);
496 | /* eslint-disable accessor-pairs */
497 | Object.defineProperty(target, 'accessor', {
498 | set: function () {}
499 | });
500 | /* eslint-enable accessor-pairs */
501 |
502 | expect(Reflect.has(target, 'accessor')).to.equal(true);
503 | });
504 |
505 | it('will search the prototype chain', function () {
506 | var Parent = function () {};
507 | Parent.prototype.someProperty = undefined;
508 |
509 | var Child = function () {};
510 | Child.prototype = new Parent();
511 |
512 | var target = new Child();
513 | target.bool = true;
514 |
515 | expect(Reflect.has(target, 'bool')).to.equal(true);
516 | expect(Reflect.has(target, 'someProperty')).to.equal(true);
517 | expect(Reflect.has(target, 'undefinedProperty')).to.equal(false);
518 | });
519 | });
520 |
521 | describeIfExtensionsPreventible('.isExtensible()', function () {
522 | if (typeof Reflect.isExtensible === 'undefined') {
523 | return it('exists', function () {
524 | expect(Reflect).to.have.property('isExtensible');
525 | });
526 | }
527 |
528 | it('is a function', function () {
529 | expect(typeof Reflect.isExtensible).to.equal('function');
530 | });
531 |
532 | ifFunctionsHaveNamesIt('has the right name', function () {
533 | expect(Reflect.isExtensible.name).to.equal('isExtensible');
534 | });
535 |
536 | it('returns true for plain objects', function () {
537 | expect(Reflect.isExtensible({})).to.equal(true);
538 | expect(Reflect.isExtensible(Object.preventExtensions({}))).to.equal(false);
539 | });
540 |
541 | it('throws if the target isn’t an object', function () {
542 | testPrimitiveThrow(function (item) {
543 | return Reflect.isExtensible(item);
544 | });
545 | });
546 | });
547 |
548 | describeIfGetOwnPropertyNames('.ownKeys()', function () {
549 | if (typeof Reflect.ownKeys === 'undefined') {
550 | return it('exists', function () {
551 | expect(Reflect).to.have.property('ownKeys');
552 | });
553 | }
554 |
555 | it('is a function', function () {
556 | expect(typeof Reflect.ownKeys).to.equal('function');
557 | });
558 |
559 | ifFunctionsHaveNamesIt('has the right name', function () {
560 | expect(Reflect.ownKeys.name).to.equal('ownKeys');
561 | });
562 |
563 | it('throws if the target isn’t an object', function () {
564 | testPrimitiveThrow(function (item) {
565 | return Reflect.ownKeys(item);
566 | });
567 | });
568 |
569 | it('should return the same result as Object.getOwnPropertyNames if there are no Symbols', function () {
570 | var obj = { foo: 1, bar: 2 };
571 |
572 | obj[1] = 'first';
573 |
574 | var result = Object.getOwnPropertyNames(obj);
575 |
576 | // Reflect.ownKeys depends on the implementation of
577 | // Object.getOwnPropertyNames, at least for non-symbol keys.
578 | expect(Reflect.ownKeys(obj)).to.deep.equal(result);
579 |
580 | // We can only be sure of which keys should exist.
581 | expect(result.sort()).to.deep.equal(['1', 'bar', 'foo']);
582 | });
583 |
584 | ifSymbolsIt('symbols come last', function () {
585 | var s = Symbol();
586 |
587 | var o = {
588 | 'non-symbol': true
589 | };
590 |
591 | o[s] = true;
592 |
593 | expect(Reflect.ownKeys(o)).to.deep.equal(['non-symbol', s]);
594 | });
595 | });
596 |
597 | describeIfExtensionsPreventible('.preventExtensions()', function () {
598 | if (typeof Reflect.preventExtensions === 'undefined') {
599 | return it('exists', function () {
600 | expect(Reflect).to.have.property('preventExtensions');
601 | });
602 | }
603 |
604 | it('is a function', function () {
605 | expect(typeof Reflect.preventExtensions).to.equal('function');
606 | });
607 |
608 | ifFunctionsHaveNamesIt('has the right name', function () {
609 | expect(Reflect.preventExtensions.name).to.equal('preventExtensions');
610 | });
611 |
612 | it('throws if the target isn’t an object', function () {
613 | testPrimitiveThrow(function (item) {
614 | return Reflect.preventExtensions(item);
615 | });
616 | });
617 |
618 | it('prevents extensions on objects', function () {
619 | var obj = {};
620 | Reflect.preventExtensions(obj);
621 | expect(Object.isExtensible(obj)).to.equal(false);
622 | });
623 | });
624 |
625 | describeIfSetProto('.setPrototypeOf()', function () {
626 | if (typeof Reflect.setPrototypeOf === 'undefined') {
627 | return it('exists', function () {
628 | expect(Reflect).to.have.property('setPrototypeOf');
629 | });
630 | }
631 |
632 | it('is a function', function () {
633 | expect(typeof Reflect.setPrototypeOf).to.equal('function');
634 | });
635 |
636 | ifFunctionsHaveNamesIt('has the right name', function () {
637 | expect(Reflect.setPrototypeOf.name).to.equal('setPrototypeOf');
638 | });
639 |
640 | it('throws if the target isn’t an object', function () {
641 | testPrimitiveThrow(function (item) {
642 | return Reflect.setPrototypeOf(item, null);
643 | });
644 | });
645 |
646 | it('throws if the prototype is neither object nor null', function () {
647 | var o = {};
648 |
649 | [undefined, 1, 'string', true].forEach(function (item) {
650 | expect(function () {
651 | return Reflect.setPrototypeOf(o, item);
652 | }).to['throw'](TypeError);
653 | });
654 | });
655 |
656 | it('can set prototypes, and returns true on success', function () {
657 | var obj = {};
658 |
659 | expect(Reflect.setPrototypeOf(obj, Array.prototype)).to.equal(true);
660 | expect(obj).to.be.an.instanceOf(Array);
661 |
662 | expect(obj.toString).not.to.equal(undefined);
663 | expect(Reflect.setPrototypeOf(obj, null)).to.equal(true);
664 | expect(obj.toString).to.equal(undefined);
665 | });
666 |
667 | ifFreezeIt('is returns false on failure', function () {
668 | var obj = Object.freeze({});
669 |
670 | expect(Reflect.setPrototypeOf(obj, null)).to.equal(false);
671 | });
672 |
673 | it('fails when attempting to create a circular prototype chain', function () {
674 | var o = {};
675 |
676 | expect(Reflect.setPrototypeOf(o, o)).to.equal(false);
677 | });
678 | });
679 | });
680 |
--------------------------------------------------------------------------------
/test/regexp.js:
--------------------------------------------------------------------------------
1 | var getRegexLiteral = function (stringRegex) {
2 | try {
3 | /* eslint-disable no-new-func */
4 | return Function('return ' + stringRegex + ';')();
5 | /* eslint-enable no-new-func */
6 | } catch (e) { /**/ }
7 | };
8 | var describeIfSupportsDescriptors = Object.getOwnPropertyDescriptor ? describe : describe.skip;
9 | var callAllowsPrimitives = (function () { return this === 3; }.call(3));
10 | var ifCallAllowsPrimitivesIt = callAllowsPrimitives ? it : it.skip;
11 | var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
12 | var hasSymbols = typeof Symbol === 'function' && typeof Symbol['for'] === 'function' && typeof Symbol('') === 'symbol';
13 | var ifSymbolsDescribe = hasSymbols ? describe : describe.skip;
14 | var defaultRegex = (function () {
15 | // Chrome Canary 51 has an undefined RegExp#toSource, and
16 | // RegExp#toString produces `/undefined/`
17 | try {
18 | return RegExp.prototype.source ? String(RegExp.prototype) : '/(?:)/';
19 | } catch (e) {
20 | return '/(?:)/';
21 | }
22 | }());
23 |
24 | describe('RegExp', function () {
25 | ifShimIt('is on the exported object', function () {
26 | var exported = require('../');
27 | expect(exported.RegExp).to.equal(RegExp);
28 | });
29 |
30 | it('can be called with no arguments', function () {
31 | var regex = RegExp();
32 | expect(String(regex)).to.equal(defaultRegex);
33 | expect(regex).to.be.an.instanceOf(RegExp);
34 | });
35 |
36 | it('can be called with null/undefined', function () {
37 | expect(String(RegExp(null))).to.equal('/null/');
38 | expect(String(RegExp(undefined))).to.equal(defaultRegex);
39 | });
40 |
41 | describe('constructor', function () {
42 | it('allows a regex as the pattern', function () {
43 | var a = /a/g;
44 | var b = new RegExp(a);
45 | if (typeof a !== 'function') {
46 | // in browsers like Safari 5, new RegExp with a regex returns the same instance.
47 | expect(a).not.to.equal(b);
48 | }
49 | expect(a).to.eql(b);
50 | });
51 |
52 | it('allows a string with flags', function () {
53 | expect(new RegExp('a', 'mgi')).to.eql(/a/gim);
54 | expect(String(new RegExp('a', 'mgi'))).to.equal('/a/gim');
55 | });
56 |
57 | it('allows a regex with flags', function () {
58 | var a = /a/g;
59 | var makeRegex = function () { return new RegExp(a, 'mi'); };
60 | expect(makeRegex).not.to['throw'](TypeError);
61 | expect(makeRegex()).to.eql(/a/mi);
62 | expect(String(makeRegex())).to.equal('/a/im');
63 | });
64 |
65 | it('works with instanceof', function () {
66 | expect(/a/g).to.be.an.instanceOf(RegExp);
67 | expect(new RegExp('a', 'im')).to.be.an.instanceOf(RegExp);
68 | expect(new RegExp(/a/g, 'im')).to.be.an.instanceOf(RegExp);
69 | });
70 |
71 | it('has the right constructor', function () {
72 | expect(/a/g).to.have.property('constructor', RegExp);
73 | expect(new RegExp('a', 'im')).to.have.property('constructor', RegExp);
74 | expect(new RegExp(/a/g, 'im')).to.have.property('constructor', RegExp);
75 | });
76 |
77 | it('toStrings properly', function () {
78 | expect(Object.prototype.toString.call(/a/g)).to.equal('[object RegExp]');
79 | expect(Object.prototype.toString.call(new RegExp('a', 'g'))).to.equal('[object RegExp]');
80 | expect(Object.prototype.toString.call(new RegExp(/a/g, 'im'))).to.equal('[object RegExp]');
81 | });
82 |
83 | it('functions as a boxed primitive wrapper', function () {
84 | var regex = /a/g;
85 | expect(RegExp(regex)).to.equal(regex);
86 | });
87 |
88 | ifSymbolsDescribe('Symbol.replace', function () {
89 | if (!hasSymbols || typeof Symbol.replace === 'undefined') {
90 | return;
91 | }
92 |
93 | it('is a function', function () {
94 | expect(RegExp.prototype).to.have.property(Symbol.replace);
95 | expect(typeof RegExp.prototype[Symbol.replace]).to.equal('function');
96 | });
97 |
98 | it('is the same as String#replace', function () {
99 | var regex = /a/g;
100 | var str = 'abc';
101 | var symbolReplace = regex[Symbol.replace](str);
102 | var stringReplace = str.replace(regex);
103 | expect(Object.keys(symbolReplace)).to.eql(Object.keys(stringReplace));
104 | expect(symbolReplace).to.eql(stringReplace);
105 | });
106 | });
107 |
108 | ifSymbolsDescribe('Symbol.search', function () {
109 | if (!hasSymbols || typeof Symbol.search === 'undefined') {
110 | return;
111 | }
112 |
113 | it('is a function', function () {
114 | expect(RegExp.prototype).to.have.property(Symbol.search);
115 | expect(typeof RegExp.prototype[Symbol.search]).to.equal('function');
116 | });
117 |
118 | it('is the same as String#search', function () {
119 | var regex = /a/g;
120 | var str = 'abc';
121 | var symbolSearch = regex[Symbol.search](str);
122 | var stringSearch = str.search(regex);
123 | expect(Object.keys(symbolSearch)).to.eql(Object.keys(stringSearch));
124 | expect(symbolSearch).to.eql(stringSearch);
125 | });
126 | });
127 |
128 | ifSymbolsDescribe('Symbol.split', function () {
129 | if (!hasSymbols || typeof Symbol.split === 'undefined') {
130 | return;
131 | }
132 |
133 | it('is a function', function () {
134 | expect(RegExp.prototype).to.have.property(Symbol.split);
135 | expect(typeof RegExp.prototype[Symbol.split]).to.equal('function');
136 | });
137 |
138 | it('is the same as String#split', function () {
139 | var regex = /a/g;
140 | var str = 'abcabc';
141 | var symbolSplit = regex[Symbol.split](str, 1);
142 | var stringSplit = str.split(regex, 1);
143 | expect(Object.keys(symbolSplit)).to.eql(Object.keys(stringSplit));
144 | expect(symbolSplit).to.eql(stringSplit);
145 | });
146 | });
147 |
148 | ifSymbolsDescribe('Symbol.match', function () {
149 | if (!hasSymbols || typeof Symbol.match === 'undefined') {
150 | return;
151 | }
152 |
153 | var regexFalsyMatch;
154 | var nonregexTruthyMatch;
155 |
156 | beforeEach(function () {
157 | regexFalsyMatch = /./;
158 | regexFalsyMatch[Symbol.match] = false;
159 | nonregexTruthyMatch = { constructor: RegExp };
160 | nonregexTruthyMatch[Symbol.match] = true;
161 | });
162 |
163 | it('is a function', function () {
164 | expect(RegExp.prototype).to.have.property(Symbol.match);
165 | expect(typeof RegExp.prototype[Symbol.match]).to.equal('function');
166 | });
167 |
168 | it('is the same as String#match', function () {
169 | var regex = /a/g;
170 | var str = 'abc';
171 | var symbolMatch = regex[Symbol.match](str);
172 | var stringMatch = str.match(regex);
173 | expect(Object.keys(symbolMatch)).to.eql(Object.keys(stringMatch));
174 | expect(symbolMatch).to.eql(stringMatch);
175 | });
176 |
177 | it('function does not passthrough regexes with a falsy Symbol.match', function () {
178 | expect(RegExp(regexFalsyMatch)).not.to.equal(regexFalsyMatch);
179 | });
180 |
181 | it('constructor does not passthrough regexes with a falsy Symbol.match', function () {
182 | expect(new RegExp(regexFalsyMatch)).not.to.equal(regexFalsyMatch);
183 | });
184 |
185 | it('function passes through non-regexes with a truthy Symbol.match', function () {
186 | expect(RegExp(nonregexTruthyMatch)).to.equal(nonregexTruthyMatch);
187 | });
188 |
189 | it('constructor does not pass through non-regexes with a truthy Symbol.match', function () {
190 | expect(new RegExp(nonregexTruthyMatch)).not.to.equal(nonregexTruthyMatch);
191 | });
192 | });
193 | });
194 |
195 | describeIfSupportsDescriptors('#flags', function () {
196 | if (!Object.prototype.hasOwnProperty.call(RegExp.prototype, 'flags')) {
197 | return it('exists', function () {
198 | expect(RegExp.prototype).to.have.property('flags');
199 | });
200 | }
201 |
202 | var regexpFlagsDescriptor = Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags');
203 | var testGenericRegExpFlags = function (object) {
204 | return regexpFlagsDescriptor.get.call(object);
205 | };
206 |
207 | it('has the correct descriptor', function () {
208 | expect(regexpFlagsDescriptor.configurable).to.equal(true);
209 | expect(regexpFlagsDescriptor.enumerable).to.equal(false);
210 | expect(regexpFlagsDescriptor.get instanceof Function).to.equal(true);
211 | expect(regexpFlagsDescriptor.set).to.equal(undefined);
212 | });
213 |
214 | ifCallAllowsPrimitivesIt('throws when not called on an object', function () {
215 | var nonObjects = ['', false, true, 42, NaN, null, undefined];
216 | nonObjects.forEach(function (nonObject) {
217 | expect(function () { testGenericRegExpFlags(nonObject); }).to['throw'](TypeError);
218 | });
219 | });
220 |
221 | it('has the correct flags on a literal', function () {
222 | expect((/a/g).flags).to.equal('g');
223 | expect((/a/i).flags).to.equal('i');
224 | expect((/a/m).flags).to.equal('m');
225 | if (Object.prototype.hasOwnProperty.call(RegExp.prototype, 'sticky')) {
226 | expect(getRegexLiteral('/a/y').flags).to.equal('y');
227 | }
228 | if (Object.prototype.hasOwnProperty.call(RegExp.prototype, 'unicode')) {
229 | expect(getRegexLiteral('/a/u').flags).to.equal('u');
230 | }
231 | });
232 |
233 | it('has the correct flags on a constructed RegExp', function () {
234 | expect(new RegExp('a', 'g').flags).to.equal('g');
235 | expect(new RegExp('a', 'i').flags).to.equal('i');
236 | expect(new RegExp('a', 'm').flags).to.equal('m');
237 | if (Object.prototype.hasOwnProperty.call(RegExp.prototype, 'sticky')) {
238 | expect(new RegExp('a', 'y').flags).to.equal('y');
239 | }
240 | if (Object.prototype.hasOwnProperty.call(RegExp.prototype, 'unicode')) {
241 | expect(new RegExp('a', 'u').flags).to.equal('u');
242 | }
243 | });
244 |
245 | it('returns flags sorted on a literal', function () {
246 | expect((/a/gim).flags).to.equal('gim');
247 | expect((/a/mig).flags).to.equal('gim');
248 | expect((/a/mgi).flags).to.equal('gim');
249 | if (Object.prototype.hasOwnProperty.call(RegExp.prototype, 'sticky')) {
250 | expect(getRegexLiteral('/a/gyim').flags).to.equal('gimy');
251 | }
252 | if (Object.prototype.hasOwnProperty.call(RegExp.prototype, 'unicode')) {
253 | expect(getRegexLiteral('/a/ugmi').flags).to.equal('gimu');
254 | }
255 | });
256 |
257 | it('returns flags sorted on a constructed RegExp', function () {
258 | expect(new RegExp('a', 'gim').flags).to.equal('gim');
259 | expect(new RegExp('a', 'mig').flags).to.equal('gim');
260 | expect(new RegExp('a', 'mgi').flags).to.equal('gim');
261 | if (Object.prototype.hasOwnProperty.call(RegExp.prototype, 'sticky')) {
262 | expect(new RegExp('a', 'mygi').flags).to.equal('gimy');
263 | }
264 | if (Object.prototype.hasOwnProperty.call(RegExp.prototype, 'unicode')) {
265 | expect(new RegExp('a', 'mugi').flags).to.equal('gimu');
266 | }
267 | });
268 | });
269 |
270 | describe('#toString()', function () {
271 | it('throws on null/undefined', function () {
272 | expect(function () { RegExp.prototype.toString.call(null); }).to['throw'](TypeError);
273 | expect(function () { RegExp.prototype.toString.call(undefined); }).to['throw'](TypeError);
274 | });
275 |
276 | it('has an undefined prototype', function () {
277 | expect(RegExp.prototype.toString.prototype).to.equal(undefined);
278 | });
279 |
280 | it('works on regexes', function () {
281 | expect(RegExp.prototype.toString.call(/a/g)).to.equal('/a/g');
282 | expect(RegExp.prototype.toString.call(new RegExp('a', 'g'))).to.equal('/a/g');
283 | });
284 |
285 | it('works on non-regexes', function () {
286 | expect(RegExp.prototype.toString.call({ source: 'abc', flags: '' })).to.equal('/abc/');
287 | expect(RegExp.prototype.toString.call({ source: 'abc', flags: 'xyz' })).to.equal('/abc/xyz');
288 | });
289 |
290 | ifSymbolsDescribe('Symbol.match', function () {
291 | if (!hasSymbols || typeof Symbol.match === 'undefined') {
292 | return;
293 | }
294 |
295 | it('accepts a non-regex with Symbol.match', function () {
296 | var obj = { source: 'abc', flags: 'def' };
297 | obj[Symbol.match] = RegExp.prototype[Symbol.match];
298 | expect(RegExp.prototype.toString.call(obj)).to.equal('/abc/def');
299 | });
300 | });
301 | });
302 |
303 | describe('Object properties', function () {
304 | it('does not have the nonstandard $input property', function () {
305 | expect(RegExp).not.to.have.property('$input'); // Chrome < 39, Opera < 26 have this
306 | });
307 |
308 | it('has "input" property', function () {
309 | expect(RegExp).to.have.ownProperty('input');
310 | expect(RegExp).to.have.ownProperty('$_');
311 | });
312 |
313 | it('has "last match" property', function () {
314 | expect(RegExp).to.have.ownProperty('lastMatch');
315 | expect(RegExp).to.have.ownProperty('$+');
316 | });
317 |
318 | it('has "last paren" property', function () {
319 | expect(RegExp).to.have.ownProperty('lastParen');
320 | expect(RegExp).to.have.ownProperty('$&');
321 | });
322 |
323 | it('has "leftContext" property', function () {
324 | expect(RegExp).to.have.ownProperty('leftContext');
325 | expect(RegExp).to.have.ownProperty('$`');
326 | });
327 |
328 | it('has "rightContext" property', function () {
329 | expect(RegExp).to.have.ownProperty('rightContext');
330 | expect(RegExp).to.have.ownProperty("$'");
331 | });
332 |
333 | it.skip('has "multiline" property', function () {
334 | // fails in IE 9, 10, 11
335 | expect(RegExp).to.have.ownProperty('multiline');
336 | expect(RegExp).to.have.ownProperty('$*');
337 | });
338 |
339 | it('has the right globals', function () {
340 | var matchVars = [
341 | '$1',
342 | '$2',
343 | '$3',
344 | '$4',
345 | '$5',
346 | '$6',
347 | '$7',
348 | '$8',
349 | '$9'
350 | ];
351 | matchVars.forEach(function (match) {
352 | expect(RegExp).to.have.property(match);
353 | });
354 | });
355 |
356 | describe('updates RegExp globals', function () {
357 | var str = 'abcdefghijklmnopq';
358 | var re;
359 | beforeEach(function () {
360 | re = /(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)(m)(n)(o)(p)/;
361 | re.exec(str);
362 | });
363 |
364 | it('has "input"', function () {
365 | expect(RegExp.input).to.equal(str);
366 | expect(RegExp.$_).to.equal(str);
367 | });
368 |
369 | it('has "multiline"', function () {
370 | if (Object.prototype.hasOwnProperty.call(RegExp, 'multiline')) {
371 | expect(RegExp.multiline).to.equal(false);
372 | }
373 | if (Object.prototype.hasOwnProperty.call(RegExp, '$*')) {
374 | expect(RegExp['$*']).to.equal(false);
375 | }
376 | });
377 |
378 | it('has "lastMatch"', function () {
379 | expect(RegExp.lastMatch).to.equal('bcdefghijklmnop');
380 | expect(RegExp['$&']).to.equal('bcdefghijklmnop');
381 | });
382 |
383 | // in all but IE, this works. IE lastParen breaks after 11 tokens.
384 | it.skip('has "lastParen"', function () {
385 | expect(RegExp.lastParen).to.equal('p');
386 | expect(RegExp['$+']).to.equal('p');
387 | });
388 | it('has "lastParen" for less than 11 tokens', function () {
389 | (/(b)(c)(d)/).exec('abcdef');
390 | expect(RegExp.lastParen).to.equal('d');
391 | expect(RegExp['$+']).to.equal('d');
392 | });
393 |
394 | it('has "leftContext"', function () {
395 | expect(RegExp.leftContext).to.equal('a');
396 | expect(RegExp['$`']).to.equal('a');
397 | });
398 |
399 | it('has "rightContext"', function () {
400 | expect(RegExp.rightContext).to.equal('q');
401 | expect(RegExp["$'"]).to.equal('q');
402 | });
403 |
404 | it('has $1 - $9', function () {
405 | expect(RegExp.$1).to.equal('b');
406 | expect(RegExp.$2).to.equal('c');
407 | expect(RegExp.$3).to.equal('d');
408 | expect(RegExp.$4).to.equal('e');
409 | expect(RegExp.$5).to.equal('f');
410 | expect(RegExp.$6).to.equal('g');
411 | expect(RegExp.$7).to.equal('h');
412 | expect(RegExp.$8).to.equal('i');
413 | expect(RegExp.$9).to.equal('j');
414 | });
415 | });
416 | });
417 | });
418 |
--------------------------------------------------------------------------------
/test/set.js:
--------------------------------------------------------------------------------
1 | // Big thanks to V8 folks for test ideas.
2 | // v8/test/mjsunit/harmony/collections.js
3 |
4 | var Assertion = expect().constructor;
5 | Assertion.addMethod('theSameSet', function (otherArray) {
6 | var array = this._obj;
7 |
8 | expect(Array.isArray(array)).to.equal(true);
9 | expect(Array.isArray(otherArray)).to.equal(true);
10 |
11 | var diff = array.filter(function (value) {
12 | return otherArray.every(function (otherValue) {
13 | var areBothNaN = typeof value === 'number' && typeof otherValue === 'number' && value !== value && otherValue !== otherValue;
14 | return !areBothNaN && value !== otherValue;
15 | });
16 | });
17 |
18 | this.assert(
19 | diff.length === 0,
20 | 'expected #{this} to be equal to #{exp} (as sets, i.e. no order)',
21 | array,
22 | otherArray
23 | );
24 | });
25 |
26 | var $iterator$ = typeof Symbol === 'function' ? Symbol.iterator : '_es6-shim iterator_';
27 | if (typeof Set === 'function' && typeof Set.prototype['@@iterator'] === 'function') {
28 | $iterator$ = '@@iterator';
29 | }
30 |
31 | Assertion.addMethod('iterations', function (expected) {
32 | var iterator = this._obj[$iterator$]();
33 |
34 | expect(Array.isArray(expected)).to.equal(true);
35 | var expectedValues = expected.slice();
36 |
37 | var result;
38 | do {
39 | result = iterator.next();
40 | expect(result.value).to.eql(expectedValues.shift());
41 | } while (!result.done);
42 | });
43 |
44 | describe('Set', function () {
45 | var functionsHaveNames = (function foo() {}).name === 'foo';
46 | var ifFunctionsHaveNamesIt = functionsHaveNames ? it : xit;
47 | var ifShimIt = (typeof process !== 'undefined' && process.env.NO_ES6_SHIM) ? it.skip : it;
48 | var ifGetPrototypeOfIt = Object.getPrototypeOf ? it : xit;
49 |
50 | var range = function (from, to) {
51 | var result = [];
52 | for (var value = from; value < to; value++) {
53 | result.push(value);
54 | }
55 | return result;
56 | };
57 |
58 | var prototypePropIsEnumerable = Object.prototype.propertyIsEnumerable.call(function () {}, 'prototype');
59 | var expectNotEnumerable = function (object) {
60 | if (prototypePropIsEnumerable && typeof object === 'function') {
61 | expect(Object.keys(object)).to.eql(['prototype']);
62 | } else {
63 | expect(Object.keys(object)).to.eql([]);
64 | }
65 | };
66 |
67 | var Sym = typeof Symbol === 'undefined' ? {} : Symbol;
68 | var isSymbol = function (sym) {
69 | return typeof Sym === 'function' && typeof sym === 'symbol';
70 | };
71 | var ifSymbolIteratorIt = isSymbol(Sym.iterator) ? it : xit;
72 |
73 | var testSet = function (set, key) {
74 | expect(set.has(key)).to.equal(false);
75 | expect(set['delete'](key)).to.equal(false);
76 | expect(set.add(key)).to.equal(set);
77 | expect(set.has(key)).to.equal(true);
78 | expect(set['delete'](key)).to.equal(true);
79 | expect(set.has(key)).to.equal(false);
80 | expect(set.add(key)).to.equal(set); // add it back
81 | };
82 |
83 | if (typeof Set === 'undefined') {
84 | return it('exists', function () {
85 | expect(typeof Set).to.equal('function');
86 | });
87 | }
88 |
89 | var set;
90 | beforeEach(function () {
91 | set = new Set();
92 | });
93 |
94 | afterEach(function () {
95 | set = null;
96 | });
97 |
98 | it('set iteration', function () {
99 | expect(set.add('a')).to.equal(set);
100 | expect(set.add('b')).to.equal(set);
101 | expect(set.add('c')).to.equal(set);
102 | expect(set.add('d')).to.equal(set);
103 |
104 | var keys = [];
105 | var iterator = set.keys();
106 | keys.push(iterator.next().value);
107 | expect(set['delete']('a')).to.equal(true);
108 | expect(set['delete']('b')).to.equal(true);
109 | expect(set['delete']('c')).to.equal(true);
110 | expect(set.add('e')).to.equal(set);
111 | keys.push(iterator.next().value);
112 | keys.push(iterator.next().value);
113 |
114 | expect(iterator.next().done).to.equal(true);
115 | expect(set.add('f')).to.equal(set);
116 | expect(iterator.next().done).to.equal(true);
117 | expect(keys).to.eql(['a', 'd', 'e']);
118 | });
119 |
120 | ifShimIt('is on the exported object', function () {
121 | var exported = require('../');
122 | expect(exported.Set).to.equal(Set);
123 | });
124 |
125 | it('should exist in global namespace', function () {
126 | expect(typeof Set).to.equal('function');
127 | });
128 |
129 | it('has the right arity', function () {
130 | expect(Set).to.have.property('length', 0);
131 | });
132 |
133 | it('returns the set from #add() for chaining', function () {
134 | expect(set.add({})).to.equal(set);
135 | });
136 |
137 | it('should return false when deleting an item not in the set', function () {
138 | expect(set.has('a')).to.equal(false);
139 | expect(set['delete']('a')).to.equal(false);
140 | });
141 |
142 | it('should accept an iterable as argument', function () {
143 | testSet(set, 'a');
144 | testSet(set, 'b');
145 | var set2 = new Set(set);
146 | expect(set2.has('a')).to.equal(true);
147 | expect(set2.has('b')).to.equal(true);
148 | expect(set2).to.have.iterations(['a', 'b']);
149 | });
150 |
151 | it('accepts an array as an argument', function () {
152 | var arr = ['a', 'b', 'c'];
153 | var setFromArray = new Set(arr);
154 | expect(setFromArray).to.have.iterations(['a', 'b', 'c']);
155 | });
156 |
157 | it('should not be callable without "new"', function () {
158 | expect(Set).to['throw'](TypeError);
159 | });
160 |
161 | it('should be subclassable', function () {
162 | if (!Object.setPrototypeOf) { return; } // skip test if on IE < 11
163 | var MySet = function MySet() {
164 | var actualSet = new Set(['a', 'b']);
165 | Object.setPrototypeOf(actualSet, MySet.prototype);
166 | return actualSet;
167 | };
168 | Object.setPrototypeOf(MySet, Set);
169 | MySet.prototype = Object.create(Set.prototype, {
170 | constructor: { value: MySet }
171 | });
172 |
173 | var mySet = new MySet();
174 | testSet(mySet, 'c');
175 | testSet(mySet, 'd');
176 | expect(mySet).to.have.iterations(['a', 'b', 'c', 'd']);
177 | });
178 |
179 | it('should has valid getter and setter calls', function () {
180 | ['add', 'has', 'delete'].forEach(function (method) {
181 | expect(function () {
182 | set[method]({});
183 | }).to.not['throw']();
184 | });
185 | });
186 |
187 | it('uses SameValueZero even on a Set of size > 4', function () {
188 | var firstFour = [1, 2, 3, 4];
189 | var fourSet = new Set(firstFour);
190 | expect(fourSet.size).to.equal(4);
191 | expect(fourSet.has(-0)).to.equal(false);
192 | expect(fourSet.has(0)).to.equal(false);
193 |
194 | fourSet.add(-0);
195 |
196 | expect(fourSet.size).to.equal(5);
197 | expect(fourSet.has(0)).to.equal(true);
198 | expect(fourSet.has(-0)).to.equal(true);
199 | });
200 |
201 | it('should work as expected', function () {
202 | // Run this test twice, one with the "fast" implementation (which only
203 | // allows string and numeric keys) and once with the "slow" impl.
204 | [true, false].forEach(function (slowkeys) {
205 | set = new Set();
206 |
207 | range(1, 20).forEach(function (number) {
208 | if (slowkeys) { testSet(set, {}); }
209 | testSet(set, number);
210 | testSet(set, number / 100);
211 | testSet(set, 'key-' + number);
212 | testSet(set, String(number));
213 | if (slowkeys) { testSet(set, Object(String(number))); }
214 | });
215 |
216 | var testkeys = [+0, Infinity, -Infinity, NaN];
217 | if (slowkeys) {
218 | testkeys.push(true, false, null, undefined);
219 | }
220 | testkeys.forEach(function (number) {
221 | testSet(set, number);
222 | testSet(set, String(number));
223 | });
224 | testSet(set, '');
225 |
226 | // -0 and +0 should be the same key (Set uses SameValueZero)
227 | expect(set.has(-0)).to.equal(true);
228 | expect(set['delete'](+0)).to.equal(true);
229 | testSet(set, -0);
230 | expect(set.has(+0)).to.equal(true);
231 |
232 | // verify that properties of Object don't peek through.
233 | [
234 | 'hasOwnProperty',
235 | 'constructor',
236 | 'toString',
237 | 'isPrototypeOf',
238 | '__proto__',
239 | '__parent__',
240 | '__count__'
241 | ].forEach(function (prop) { testSet(set, prop); });
242 | });
243 | });
244 |
245 | describe('#size', function () {
246 | it('returns the expected size', function () {
247 | expect(set.add(1)).to.equal(set);
248 | expect(set.add(5)).to.equal(set);
249 | expect(set.size).to.equal(2);
250 | });
251 | });
252 |
253 | describe('#clear()', function () {
254 | ifFunctionsHaveNamesIt('has the right name', function () {
255 | expect(Set.prototype.clear).to.have.property('name', 'clear');
256 | });
257 |
258 | it('is not enumerable', function () {
259 | expect(Set.prototype).ownPropertyDescriptor('clear').to.have.property('enumerable', false);
260 | });
261 |
262 | it('has the right arity', function () {
263 | expect(Set.prototype.clear).to.have.property('length', 0);
264 | });
265 |
266 | it('clears a Set with only primitives', function () {
267 | expect(set.add(1)).to.equal(set);
268 | expect(set.size).to.equal(1);
269 | expect(set.add(5)).to.equal(set);
270 | expect(set.size).to.equal(2);
271 | expect(set.has(5)).to.equal(true);
272 | set.clear();
273 | expect(set.size).to.equal(0);
274 | expect(set.has(5)).to.equal(false);
275 | });
276 |
277 | it('clears a Set with primitives and objects', function () {
278 | expect(set.add(1)).to.equal(set);
279 | expect(set.size).to.equal(1);
280 | var obj = {};
281 | expect(set.add(obj)).to.equal(set);
282 | expect(set.size).to.equal(2);
283 | expect(set.has(obj)).to.equal(true);
284 | set.clear();
285 | expect(set.size).to.equal(0);
286 | expect(set.has(obj)).to.equal(false);
287 | });
288 | });
289 |
290 | describe('#keys()', function () {
291 | if (!Object.prototype.hasOwnProperty.call(Set.prototype, 'keys')) {
292 | return it('exists', function () {
293 | expect(Set.prototype).to.have.property('keys');
294 | });
295 | }
296 |
297 | it('is the same object as #values()', function () {
298 | expect(Set.prototype.keys).to.equal(Set.prototype.values);
299 | });
300 |
301 | ifFunctionsHaveNamesIt('has the right name', function () {
302 | expect(Set.prototype.keys).to.have.property('name', 'values');
303 | });
304 |
305 | it('is not enumerable', function () {
306 | expect(Set.prototype).ownPropertyDescriptor('keys').to.have.property('enumerable', false);
307 | });
308 |
309 | it('has the right arity', function () {
310 | expect(Set.prototype.keys).to.have.property('length', 0);
311 | });
312 | });
313 |
314 | describe('#values()', function () {
315 | if (!Object.prototype.hasOwnProperty.call(Set.prototype, 'values')) {
316 | return it('exists', function () {
317 | expect(Set.prototype).to.have.property('values');
318 | });
319 | }
320 |
321 | ifFunctionsHaveNamesIt('has the right name', function () {
322 | expect(Set.prototype.values).to.have.property('name', 'values');
323 | });
324 |
325 | it('is not enumerable', function () {
326 | expect(Set.prototype).ownPropertyDescriptor('values').to.have.property('enumerable', false);
327 | });
328 |
329 | it('has the right arity', function () {
330 | expect(Set.prototype.values).to.have.property('length', 0);
331 | });
332 |
333 | it('throws when called on a non-Set', function () {
334 | var expectedMessage = /^(Method )?Set.prototype.values called on incompatible receiver |^values method called on incompatible |^Cannot create a Set value iterator for a non-Set object.$|^Set.prototype.values: 'this' is not a Set object$|^std_Set_iterator method called on incompatible \w+$|Set.prototype.values requires that \|this\| be Set| is not an object|Set operation called on non-Set object/;
335 | var nonSets = [true, false, 'abc', NaN, new Map([[1, 2]]), { a: true }, [1], Object('abc'), Object(NaN)];
336 | nonSets.forEach(function (nonSet) {
337 | expect(function () { return Set.prototype.values.call(nonSet); }).to['throw'](TypeError, expectedMessage);
338 | });
339 | });
340 | });
341 |
342 | describe('#entries()', function () {
343 | if (!Object.prototype.hasOwnProperty.call(Set.prototype, 'entries')) {
344 | return it('exists', function () {
345 | expect(Set.prototype).to.have.property('entries');
346 | });
347 | }
348 |
349 | ifFunctionsHaveNamesIt('has the right name', function () {
350 | expect(Set.prototype.entries).to.have.property('name', 'entries');
351 | });
352 |
353 | it('is not enumerable', function () {
354 | expect(Set.prototype).ownPropertyDescriptor('entries').to.have.property('enumerable', false);
355 | });
356 |
357 | it('has the right arity', function () {
358 | expect(Set.prototype.entries).to.have.property('length', 0);
359 | });
360 | });
361 |
362 | describe('#has()', function () {
363 | if (!Object.prototype.hasOwnProperty.call(Set.prototype, 'has')) {
364 | return it('exists', function () {
365 | expect(Set.prototype).to.have.property('has');
366 | });
367 | }
368 |
369 | ifFunctionsHaveNamesIt('has the right name', function () {
370 | expect(Set.prototype.has).to.have.property('name', 'has');
371 | });
372 |
373 | it('is not enumerable', function () {
374 | expect(Set.prototype).ownPropertyDescriptor('has').to.have.property('enumerable', false);
375 | });
376 |
377 | it('has the right arity', function () {
378 | expect(Set.prototype.has).to.have.property('length', 1);
379 | });
380 | });
381 |
382 | it('should allow NaN values as keys', function () {
383 | expect(set.has(NaN)).to.equal(false);
384 | expect(set.has(NaN + 1)).to.equal(false);
385 | expect(set.has(23)).to.equal(false);
386 | expect(set.add(NaN)).to.equal(set);
387 | expect(set.has(NaN)).to.equal(true);
388 | expect(set.has(NaN + 1)).to.equal(true);
389 | expect(set.has(23)).to.equal(false);
390 | });
391 |
392 | it('should not have [[Enumerable]] props', function () {
393 | expectNotEnumerable(Set);
394 | expectNotEnumerable(Set.prototype);
395 | expectNotEnumerable(new Set());
396 | });
397 |
398 | it('should not have an own constructor', function () {
399 | var s = new Set();
400 | expect(s).not.to.haveOwnPropertyDescriptor('constructor');
401 | expect(s.constructor).to.equal(Set);
402 | });
403 |
404 | it('should allow common ecmascript idioms', function () {
405 | expect(set instanceof Set).to.equal(true);
406 | expect(typeof Set.prototype.add).to.equal('function');
407 | expect(typeof Set.prototype.has).to.equal('function');
408 | expect(typeof Set.prototype['delete']).to.equal('function');
409 | });
410 |
411 | it('should have a unique constructor', function () {
412 | expect(Set.prototype).to.not.equal(Object.prototype);
413 | });
414 |
415 | describe('has an iterator that works with Array.from', function () {
416 | if (!Object.prototype.hasOwnProperty.call(Array, 'from')) {
417 | return it('requires Array.from to exist', function () {
418 | expect(Array).to.have.property('from');
419 | });
420 | }
421 |
422 | var values = [1, NaN, false, true, null, undefined, 'a'];
423 |
424 | it('works with the full set', function () {
425 | expect(new Set(values)).to.have.iterations(values);
426 | });
427 |
428 | it('works with Set#keys()', function () {
429 | expect(new Set(values).keys()).to.have.iterations(values);
430 | });
431 |
432 | it('works with Set#values()', function () {
433 | expect(new Set(values).values()).to.have.iterations(values);
434 | });
435 |
436 | it('works with Set#entries()', function () {
437 | expect(new Set(values).entries()).to.have.iterations([
438 | [1, 1],
439 | [NaN, NaN],
440 | [false, false],
441 | [true, true],
442 | [null, null],
443 | [undefined, undefined],
444 | ['a', 'a']
445 | ]);
446 | });
447 | });
448 |
449 | ifSymbolIteratorIt('has the right default iteration function', function () {
450 | // fixed in Webkit https://bugs.webkit.org/show_bug.cgi?id=143838
451 | expect(Set.prototype).to.have.property(Sym.iterator, Set.prototype.values);
452 | });
453 |
454 | it('should preserve insertion order', function () {
455 | var arr1 = ['d', 'a', 'b'];
456 | var arr2 = [3, 2, 'z', 'a', 1];
457 | var arr3 = [3, 2, 'z', {}, 'a', 1];
458 |
459 | [arr1, arr2, arr3].forEach(function (array) {
460 | expect(new Set(array)).to.have.iterations(array);
461 | });
462 | });
463 |
464 | describe('#forEach', function () {
465 | var setToIterate;
466 | beforeEach(function () {
467 | setToIterate = new Set();
468 | expect(setToIterate.add('a')).to.equal(setToIterate);
469 | expect(setToIterate.add('b')).to.equal(setToIterate);
470 | expect(setToIterate.add('c')).to.equal(setToIterate);
471 | });
472 |
473 | afterEach(function () {
474 | setToIterate = null;
475 | });
476 |
477 | ifFunctionsHaveNamesIt('has the right name', function () {
478 | expect(Set.prototype.forEach).to.have.property('name', 'forEach');
479 | });
480 |
481 | it('is not enumerable', function () {
482 | expect(Set.prototype).ownPropertyDescriptor('forEach').to.have.property('enumerable', false);
483 | });
484 |
485 | it('has the right arity', function () {
486 | expect(Set.prototype.forEach).to.have.property('length', 1);
487 | });
488 |
489 | it('should be iterable via forEach', function () {
490 | var expectedSet = ['a', 'b', 'c'];
491 | var foundSet = [];
492 | setToIterate.forEach(function (value, alsoValue, entireSet) {
493 | expect(entireSet).to.equal(setToIterate);
494 | expect(value).to.equal(alsoValue);
495 | foundSet.push(value);
496 | });
497 | expect(foundSet).to.eql(expectedSet);
498 | });
499 |
500 | it('should iterate over empty keys', function () {
501 | var setWithEmptyKeys = new Set();
502 | var expectedKeys = [{}, null, undefined, '', NaN, 0];
503 | expectedKeys.forEach(function (key) {
504 | expect(setWithEmptyKeys.add(key)).to.equal(setWithEmptyKeys);
505 | });
506 | var foundKeys = [];
507 | setWithEmptyKeys.forEach(function (value, key, entireSet) {
508 | expect([key]).to.be.theSameSet([value]); // handles NaN correctly
509 | expect(entireSet.has(key)).to.equal(true);
510 | foundKeys.push(key);
511 | });
512 | expect(foundKeys).to.be.theSameSet(expectedKeys);
513 | });
514 |
515 | it('should support the thisArg', function () {
516 | var context = function () {};
517 | setToIterate.forEach(function () {
518 | expect(this).to.equal(context);
519 | }, context);
520 | });
521 |
522 | it('should have a length of 1', function () {
523 | expect(Set.prototype.forEach.length).to.equal(1);
524 | });
525 |
526 | it('should not revisit modified keys', function () {
527 | var hasModifiedA = false;
528 | setToIterate.forEach(function (value, key) {
529 | if (!hasModifiedA && key === 'a') {
530 | expect(setToIterate.add('a')).to.equal(setToIterate);
531 | hasModifiedA = true;
532 | } else {
533 | expect(key).not.to.equal('a');
534 | }
535 | });
536 | });
537 |
538 | it('visits keys added in the iterator', function () {
539 | var hasAdded = false;
540 | var hasFoundD = false;
541 | setToIterate.forEach(function (value, key) {
542 | if (!hasAdded) {
543 | expect(setToIterate.add('d')).to.equal(setToIterate);
544 | hasAdded = true;
545 | } else if (key === 'd') {
546 | hasFoundD = true;
547 | }
548 | });
549 | expect(hasFoundD).to.equal(true);
550 | });
551 |
552 | it('visits keys added in the iterator when there is a deletion (slow path)', function () {
553 | var hasSeenFour = false;
554 | var setToMutate = new Set();
555 | expect(setToMutate.add({})).to.equal(setToMutate); // force use of the slow O(N) implementation
556 | expect(setToMutate.add('0')).to.equal(setToMutate);
557 | setToMutate.forEach(function (value, key) {
558 | if (key === '0') {
559 | expect(setToMutate['delete']('0')).to.equal(true);
560 | expect(setToMutate.add('4')).to.equal(setToMutate);
561 | } else if (key === '4') {
562 | hasSeenFour = true;
563 | }
564 | });
565 | expect(hasSeenFour).to.equal(true);
566 | });
567 |
568 | it('visits keys added in the iterator when there is a deletion (fast path)', function () {
569 | var hasSeenFour = false;
570 | var setToMutate = new Set();
571 | expect(setToMutate.add('0')).to.equal(setToMutate);
572 | setToMutate.forEach(function (value, key) {
573 | if (key === '0') {
574 | expect(setToMutate['delete']('0')).to.equal(true);
575 | expect(setToMutate.add('4')).to.equal(setToMutate);
576 | } else if (key === '4') {
577 | hasSeenFour = true;
578 | }
579 | });
580 | expect(hasSeenFour).to.equal(true);
581 | });
582 |
583 | it('does not visit keys deleted before a visit', function () {
584 | var hasVisitedC = false;
585 | var hasDeletedC = false;
586 | setToIterate.forEach(function (value, key) {
587 | if (key === 'c') {
588 | hasVisitedC = true;
589 | }
590 | if (!hasVisitedC && !hasDeletedC) {
591 | hasDeletedC = setToIterate['delete']('c');
592 | expect(hasDeletedC).to.equal(true);
593 | }
594 | });
595 | expect(hasVisitedC).to.equal(false);
596 | });
597 |
598 | it('should work after deletion of the current key', function () {
599 | var expectedSet = {
600 | a: 'a',
601 | b: 'b',
602 | c: 'c'
603 | };
604 | var foundSet = {};
605 | setToIterate.forEach(function (value, key) {
606 | foundSet[key] = value;
607 | expect(setToIterate['delete'](key)).to.equal(true);
608 | });
609 | expect(foundSet).to.eql(expectedSet);
610 | });
611 |
612 | it('should convert key -0 to +0', function () {
613 | var zeroSet = new Set();
614 | var result = [];
615 | expect(zeroSet.add(-0)).to.equal(zeroSet);
616 | zeroSet.forEach(function (key) {
617 | result.push(String(1 / key));
618 | });
619 | expect(zeroSet.add(1)).to.equal(zeroSet);
620 | expect(zeroSet.add(0)).to.equal(zeroSet); // shouldn't cause reordering
621 | zeroSet.forEach(function (key) {
622 | result.push(String(1 / key));
623 | });
624 | expect(result.join(', ')).to.equal('Infinity, Infinity, 1');
625 | });
626 | });
627 |
628 | it('Set.prototype.size should throw TypeError', function () {
629 | // see https://github.com/paulmillr/es6-shim/issues/176
630 | expect(function () { return Set.prototype.size; }).to['throw'](TypeError);
631 | expect(function () { return Set.prototype.size; }).to['throw'](TypeError);
632 | });
633 |
634 | it.skip('should throw proper errors when user invokes methods with wrong types of receiver', function () {
635 | });
636 |
637 | ifGetPrototypeOfIt('SetIterator identification test prototype inequality', function () {
638 | var mapEntriesProto = Object.getPrototypeOf(new Map().entries());
639 | var setEntriesProto = Object.getPrototypeOf(new Set().entries());
640 | expect(mapEntriesProto).to.not.equal(setEntriesProto);
641 | });
642 |
643 | it('SetIterator identification', function () {
644 | var fnSetValues = Set.prototype.values;
645 | var setSentinel = new Set(['SetSentinel']);
646 | var testSet1 = new Set();
647 | var testSetValues = testSet1.values();
648 | expect(testSetValues.next.call(fnSetValues.call(setSentinel)).value).to.equal('SetSentinel');
649 |
650 | var testMap = new Map();
651 | var testMapValues = testMap.values();
652 | expect(function () {
653 | return testMapValues.next.call(fnSetValues.call(setSentinel)).value;
654 | }).to['throw'](TypeError);
655 | });
656 | });
657 |
--------------------------------------------------------------------------------
/test/test_helpers.js:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line no-native-reassign, no-implicit-globals, no-global-assign
2 | expect = (function () {
3 | var chai = require('chai');
4 | chai.config.includeStack = true;
5 | return chai.expect;
6 | }());
7 |
8 | // eslint-disable-next-line no-native-reassign, no-implicit-globals, no-global-assign
9 | assert = (function () {
10 | var chai = require('chai');
11 | chai.config.includeStack = true;
12 | return chai.assert;
13 | }());
14 |
15 | if (typeof process === 'undefined' || !process.env.NO_ES6_SHIM) {
16 | require('../');
17 | }
18 |
--------------------------------------------------------------------------------
/test/worker-runner.workerjs:
--------------------------------------------------------------------------------
1 | importScripts(
2 | '../node_modules/es5-shim/es5-shim.js',
3 | '../node_modules/es5-shim/es5-sham.js',
4 | '../es6-shim.js'
5 | );
6 |
7 | postMessage('ready');
8 |
--------------------------------------------------------------------------------
/test/worker-test.js:
--------------------------------------------------------------------------------
1 | describe('Worker', function () {
2 | var workerErrorEventToError = function (errorEvent) {
3 | var errorText = 'Error in Worker';
4 | if (errorEvent.filename !== undefined) {
5 | errorText += ' ' + errorEvent.filename;
6 | }
7 | if (errorEvent.lineno !== undefined) {
8 | errorText += '(' + errorEvent.lineno + ')';
9 | }
10 | if (errorEvent.message !== undefined) {
11 | errorText += ': ' + errorEvent.message;
12 | }
13 | return new Error(errorText);
14 | };
15 | var canRunWorkerTestInCurrentContext = function () {
16 | var workerConstructorExists = typeof Worker !== 'undefined';
17 | var locationPropertyExists = typeof location !== 'undefined';
18 | var runningOnFileUriScheme = locationPropertyExists && location.protocol === 'file:';
19 |
20 | // The Worker constructor doesn't exist in some older browsers nor does it exist in non-browser contexts like Node.
21 | // Additionally some browsers (at least Chrome) don't allow Workers over file URIs.
22 | // To prevent false negative test failures in the cases where Workers are unavailable for either of those reasons
23 | // we skip this test.
24 | return workerConstructorExists && !runningOnFileUriScheme;
25 | };
26 |
27 | if (canRunWorkerTestInCurrentContext()) {
28 | it('can import es6-shim', function (done) {
29 | var worker = new Worker('worker-runner.workerjs');
30 | worker.addEventListener('error', function (errorEvent) { throw workerErrorEventToError(errorEvent); });
31 | worker.addEventListener('message', function (messageEvent) {
32 | expect(messageEvent.data).to.eql('ready');
33 | done();
34 | });
35 | });
36 | }
37 | });
38 |
--------------------------------------------------------------------------------
/testling.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | es6-shim tests
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------