diff --git a/developer-extension/src/common/extension.types.ts b/developer-extension/src/common/extension.types.ts
index 131e32ce5d..a1036be3dc 100644
--- a/developer-extension/src/common/extension.types.ts
+++ b/developer-extension/src/common/extension.types.ts
@@ -8,6 +8,11 @@ export type BackgroundToDevtoolsMessage = {
message: SdkMessage
}
+export type BackgroundTestResult = {
+ id: string
+ status: 'running' | 'passed' | 'failed'
+}
+
export type DevtoolsToBackgroundMessage = {
type: 'update-net-request-rules'
options: NetRequestRulesOptions
@@ -42,6 +47,10 @@ export type SdkMessage =
segment: BrowserSegmentMetadata
}
}
+ | {
+ type: 'test-result'
+ payload: BackgroundTestResult
+ }
export type EventCollectionStrategy = 'sdk' | 'requests'
diff --git a/developer-extension/src/common/panelTabConstants.ts b/developer-extension/src/common/panelTabConstants.ts
index f0fb92b2d7..b222323dea 100644
--- a/developer-extension/src/common/panelTabConstants.ts
+++ b/developer-extension/src/common/panelTabConstants.ts
@@ -1,8 +1,9 @@
export const enum PanelTabs {
+ Diagnostics = 'diagnostics',
Events = 'events',
Infos = 'infos',
- Settings = 'settings',
Replay = 'replay',
+ Settings = 'settings',
}
export const DEFAULT_PANEL_TAB = PanelTabs.Events
diff --git a/developer-extension/src/content-scripts/main.ts b/developer-extension/src/content-scripts/main.ts
index 7b79335a62..e66db261af 100644
--- a/developer-extension/src/content-scripts/main.ts
+++ b/developer-extension/src/content-scripts/main.ts
@@ -14,7 +14,7 @@ declare global {
type SdkPublicApi = { [key: string]: (...args: any[]) => unknown }
function main() {
- // Prevent multiple executions when the devetools are reconnecting
+ // Prevent multiple executions when the devtools are reconnecting
if (window.__ddBrowserSdkExtensionCallback) {
return
}
diff --git a/developer-extension/src/panel/components/panel.tsx b/developer-extension/src/panel/components/panel.tsx
index 8f57b83389..fb946b29da 100644
--- a/developer-extension/src/panel/components/panel.tsx
+++ b/developer-extension/src/panel/components/panel.tsx
@@ -13,6 +13,7 @@ import { SettingsTab } from './tabs/settingsTab'
import { InfosTab } from './tabs/infosTab'
import { EventsTab, DEFAULT_COLUMNS } from './tabs/eventsTab'
import { ReplayTab } from './tabs/replayTab'
+import { DiagnosticsTab } from './tabs/diagnosticTab'
import * as classes from './panel.module.css'
@@ -65,6 +66,7 @@ export function Panel() {
>
Settings
+ Diagnostics
+
+
+
)
}
diff --git a/developer-extension/src/panel/components/tabs/diagnosticTab/apiDiagnosticsTable.tsx b/developer-extension/src/panel/components/tabs/diagnosticTab/apiDiagnosticsTable.tsx
new file mode 100644
index 0000000000..9c71953ccb
--- /dev/null
+++ b/developer-extension/src/panel/components/tabs/diagnosticTab/apiDiagnosticsTable.tsx
@@ -0,0 +1,112 @@
+import React from 'react'
+import { Badge, Card, Flex, Text } from '@mantine/core'
+import { Alert } from '../../alert'
+import type { ApiDiagnostic, ApiDiagnosticLevel, ApiPathComponent } from '../../../hooks/useApiDiagnostics'
+import { useApiDiagnostics } from '../../../hooks/useApiDiagnostics'
+
+const DIAGNOSTIC_LEVEL_COLOR: { [level in ApiDiagnosticLevel]: string } = {
+ error: 'red',
+ info: 'teal',
+ warning: 'orange',
+}
+
+export function ApiDiagnosticsTable() {
+ const apiDiagnostics = useApiDiagnostics()
+
+ switch (apiDiagnostics?.status) {
+ case undefined:
+ return
+
+ case 'error':
+ return
+
+ case 'success':
+ return (
+
+ {apiDiagnostics.diagnostics.map((diagnostic) => (
+
+ ))}
+
+ )
+ }
+}
+
+function ApiDiagnosticRow({ diagnostic }: { diagnostic: ApiDiagnostic }) {
+ return (
+
+
+
+
+
+
+ )
+}
+
+function ApiDiagnosticBadge({ level }: { level: ApiDiagnosticLevel }) {
+ return (
+
+ {level}
+
+ )
+}
+
+function ApiDiagnosticDescription({ subject, message }: { subject: ApiPathComponent[]; message: string }) {
+ // Drop the leading 'window' component unless it's interesting (e.g. because we're
+ // talking about a getter or setter directly on the global object, or the global
+ // object's prototype).
+ const components =
+ subject.length >= 2 && subject[0].name === 'window' && subject[1].type !== 'value' ? subject : subject.slice(1)
+
+ // We can render the path in a compact way if only one component remains, or if
+ // two remain, but the first one is a normal value property. In other situations,
+ // we'll use an expanded rendering that takes up more space vertically but looks
+ // better for complex paths and requires much less horizontal space.
+ const useCompactPath = components.length === 1 || (components.length === 2 && components[0].type === 'value')
+
+ return (
+
+ {useCompactPath ? (
+
+ ) : (
+
+ )}
+ {message}
+
+ )
+}
+
+function ApiDiagnosticCompactPath({ components }: { components: ApiPathComponent[] }) {
+ return {components.map(formatPathComponentText).join('.')}
+}
+
+function ApiDiagnosticExpandedPath({ components }: { components: ApiPathComponent[] }) {
+ return components.map((component, index) => )
+}
+
+function ApiDiagnosticPathComponent({ component, index }: { component: ApiPathComponent; index: number }) {
+ const leadingDot = index === 0 ? '' : '.'
+ const text = `${leadingDot}${formatPathComponentText(component)}`
+ const marginLeft = index === 0 ? '0' : '1em'
+ return {text}
+}
+
+function formatPathComponentText(component: ApiPathComponent): string {
+ switch (component.type) {
+ case 'prototype':
+ return `__proto__ (${component.name})`
+ case 'value':
+ return `${component.name}`
+ case 'get':
+ return `${component.name} (get)`
+ case 'set':
+ return `${component.name} (set)`
+ }
+}
diff --git a/developer-extension/src/panel/components/tabs/diagnosticTab/data/custom.ts b/developer-extension/src/panel/components/tabs/diagnosticTab/data/custom.ts
new file mode 100644
index 0000000000..aa5ef398c4
--- /dev/null
+++ b/developer-extension/src/panel/components/tabs/diagnosticTab/data/custom.ts
@@ -0,0 +1,31 @@
+import type { Test } from '../../../../hooks/useTest'
+
+declare function asyncTestPassed(): void
+declare function asyncTestFailed(): void
+
+export const data: Test[] = [
+ {
+ name: 'XMLHttpRequest',
+ subtests: [
+ {
+ name: 'generates trusted events',
+ category: 'datadog',
+ exec() {
+ const request = new XMLHttpRequest()
+ // TODO pot to proxy or to datadog intake to go around CSP
+ request.open('POST', 'https://7fc280bc.datadoghq.com/api/v2/logs', true)
+
+ request.addEventListener(
+ 'loadend',
+ (event) => {
+ event.isTrusted ? asyncTestPassed() : asyncTestFailed()
+ },
+ { once: true }
+ )
+
+ request.send('')
+ },
+ },
+ ],
+ },
+]
diff --git a/developer-extension/src/panel/components/tabs/diagnosticTab/data/es2016plus.ts b/developer-extension/src/panel/components/tabs/diagnosticTab/data/es2016plus.ts
new file mode 100644
index 0000000000..7f2cf4e9d8
--- /dev/null
+++ b/developer-extension/src/panel/components/tabs/diagnosticTab/data/es2016plus.ts
@@ -0,0 +1,8919 @@
+/* eslint-disable */
+// @ts-nocheck
+
+const babel = {}
+const typescript = {}
+const firefox = {}
+const chrome = {}
+const edge = {}
+const graalvm = {}
+
+export const data = [
+ {
+ name: 'exponentiation (**) operator',
+ category: '2016 features',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/7.0/index.html#sec-exp-operator',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Arithmetic_Operators#Exponentiation_(**)',
+ subtests: [
+ {
+ name: 'basic support',
+ exec() {
+ /*
+ return 2 ** 3 === 8 && -(5 ** 2) === -25 && (-5) ** 2 === 25;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox42: firefox.nightly,
+ firefox52: true,
+ opera10_50: false,
+ chrome51: chrome.experimental,
+ chrome52: true,
+ safari10_1: true,
+ duktape2_0: true,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'assignment',
+ exec() {
+ /*
+ var a = 2; a **= 3; return a === 8;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox48: firefox.nightly,
+ firefox52: true,
+ opera10_50: false,
+ chrome51: chrome.experimental,
+ chrome52: true,
+ safari10_1: true,
+ duktape2_0: true,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'early syntax error for unary negation without parens',
+ exec() {
+ /*
+ if (2 ** 3 !== 8) { return false; }
+ try {
+ Function ("-5 ** 2")();
+ } catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ chrome51: chrome.experimental,
+ chrome52: true,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Object static methods',
+ spec: 'https://tc39.github.io/ecma262/#sec-properties-of-the-object-constructor',
+ category: '2017 features',
+ significance: 'medium',
+ subtests: [
+ {
+ name: 'Object.values',
+ spec: 'https://tc39.github.io/ecma262/#sec-object.values',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/values',
+ category: '2017 features',
+ significance: 'medium',
+ exec() {
+ /*
+ var obj = Object.create({ a: "qux", d: "qux" });
+ obj.a = "foo";
+ obj.b = "bar";
+ obj.c = "baz";
+ var v = Object.values(obj);
+ return Array.isArray(v) && String(v) === "foo,bar,baz";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ es7shim: true,
+ typescript1corejs2: typescript.corejs,
+ firefox2: false,
+ firefox45: firefox.nightly,
+ firefox47: true,
+ opera10_50: false,
+ chrome51: chrome.experimental,
+ chrome54: true,
+ ie11: false,
+ edge14: true,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Object.entries',
+ spec: 'https://tc39.github.io/ecma262/#sec-object.entries',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/entries',
+ exec() {
+ /*
+ var obj = Object.create({ a: "qux", d: "qux" });
+ obj.a = "foo";
+ obj.b = "bar";
+ obj.c = "baz";
+ var e = Object.entries(obj);
+ return Array.isArray(e)
+ && e.length === 3
+ && String(e[0]) === "a,foo"
+ && String(e[1]) === "b,bar"
+ && String(e[2]) === "c,baz";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ es7shim: true,
+ typescript1corejs2: typescript.corejs,
+ firefox2: false,
+ firefox45: firefox.nightly,
+ firefox47: true,
+ opera10_50: false,
+ chrome51: chrome.experimental,
+ chrome54: true,
+ ie11: false,
+ edge14: true,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Object.getOwnPropertyDescriptors',
+ spec: 'https://tc39.github.io/ecma262/#sec-object.getownpropertydescriptors',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptors',
+ exec() {
+ /*
+ var object = {a: 1};
+ var B = typeof Symbol === 'function' ? Symbol('b') : 'b';
+ object[B] = 2;
+ var O = Object.defineProperty(object, 'c', {value: 3});
+ var D = Object.getOwnPropertyDescriptors(O);
+
+ return D.a.value === 1 && D.a.enumerable === true && D.a.configurable === true && D.a.writable === true
+ && D[B].value === 2 && D[B].enumerable === true && D[B].configurable === true && D[B].writable === true
+ && D.c.value === 3 && D.c.enumerable === false && D.c.configurable === false && D.c.writable === false;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ es7shim: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ chrome51: chrome.experimental,
+ chrome54: true,
+ firefox2: false,
+ firefox50: true,
+ opera10_50: false,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: "Object.getOwnPropertyDescriptors doesn't provide undefined descriptors",
+ exec() {
+ /*
+ var P = new Proxy({ a: 1 }, {
+ getOwnPropertyDescriptor: function (t, k) {}
+ });
+ return !Object.getOwnPropertyDescriptors(P).hasOwnProperty('a');
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox50: true,
+ opera10_50: false,
+ chrome54: true,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Array.prototype.includes',
+ spec: 'http://www.ecma-international.org/ecma-262/7.0/index.html#sec-array.prototype.includes',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes',
+ category: '2016 features',
+ significance: 'small',
+ subtests: [
+ {
+ name: 'Array.prototype.includes',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes',
+ exec() {
+ /*
+ return [1, 2, 3].includes(1)
+ && ![1, 2, 3].includes(4)
+ && ![1, 2, 3].includes(1, 1)
+ && [NaN].includes(NaN);
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ es7shim: true,
+ typescript1corejs2: typescript.corejs,
+ safari9: true,
+ chrome47: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox43: true,
+ opera10_50: false,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.prototype.includes handles sparse arrays',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/includes',
+ exec() {
+ /*
+ return [,].includes()
+ && Array(1).includes();
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ es7shim: true,
+ typescript1corejs2: typescript.corejs,
+ safari9: true,
+ chrome47: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox43: true,
+ firefox99: false,
+ firefox102: true,
+ opera10_50: false,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.prototype.includes is generic',
+ exec() {
+ /*
+ var passed = 0;
+ return [].includes.call(
+ {
+ get "0"() {
+ passed = NaN;
+ return 'foo';
+ },
+ get "11"() {
+ passed += 1;
+ return 0;
+ },
+ get "19"() {
+ passed += 1;
+ return 'foo';
+ },
+ get "21"() {
+ passed = NaN;
+ return 'foo';
+ },
+ get length() {
+ passed += 1;
+ return 24;
+ }
+ },
+ 'foo',
+ 6
+ ) === true && passed === 3;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20180402: true,
+ es7shim: true,
+ typescript1corejs2: typescript.corejs,
+ safari9: true,
+ chrome47: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox43: true,
+ opera10_50: false,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: '%TypedArray%.prototype.includes',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/includes',
+ exec() {
+ /*
+ return [
+ Int8Array,
+ Uint8Array,
+ Uint8ClampedArray,
+ Int16Array,
+ Uint16Array,
+ Int32Array,
+ Uint32Array,
+ Float32Array,
+ Float64Array
+ ].every(function (TypedArray) {
+ return new TypedArray([1, 2, 3]).includes(1)
+ && !new TypedArray([1, 2, 3]).includes(4)
+ && !new TypedArray([1, 2, 3]).includes(1, 1);
+ });
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ chrome47: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox43: true,
+ opera10_50: false,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'String padding',
+ category: '2017 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-string-pad-start-end',
+ subtests: [
+ {
+ name: 'String.prototype.padStart',
+ spec: 'https://tc39.github.io/ecma262/#sec-string.prototype.padstart',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart',
+ exec() {
+ /*
+ return 'hello'.padStart(10) === ' hello'
+ && 'hello'.padStart(10, '1234') === '12341hello'
+ && 'hello'.padStart() === 'hello'
+ && 'hello'.padStart(6, '123') === '1hello'
+ && 'hello'.padStart(3) === 'hello'
+ && 'hello'.padStart(3, '123') === 'hello';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ es7shim: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ ie11: false,
+ edge14: edge.experimental,
+ edge15: true,
+ chrome52: chrome.experimental,
+ chrome57: true,
+ node8: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.padEnd',
+ spec: 'https://tc39.github.io/ecma262/#sec-string.prototype.padend',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padEnd',
+ exec() {
+ /*
+ return 'hello'.padEnd(10) === 'hello '
+ && 'hello'.padEnd(10, '1234') === 'hello12341'
+ && 'hello'.padEnd() === 'hello'
+ && 'hello'.padEnd(6, '123') === 'hello1'
+ && 'hello'.padEnd(3) === 'hello'
+ && 'hello'.padEnd(3, '123') === 'hello';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ es7shim: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ ie11: false,
+ edge14: edge.experimental,
+ edge15: true,
+ chrome52: chrome.experimental,
+ chrome57: true,
+ node8: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'trailing commas in function syntax',
+ spec: 'https://github.com/tc39/proposal-trailing-function-commas',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Trailing_commas',
+ category: '2017 features',
+ significance: 'small',
+ subtests: [
+ {
+ name: 'in parameter lists',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Trailing_commas#Parameter_definitions',
+ exec() {
+ /*
+ return typeof function f( a, b, ) {} === 'function';
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ typescript2corejs2: true,
+ ie11: false,
+ edge14: true,
+ chrome57: chrome.experimental,
+ chrome58: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ node8: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'in argument lists',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Trailing_commas#Function_calls',
+ exec() {
+ /*
+ return Math.min(1,2,3,) === 1;
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ typescript2corejs2: true,
+ ie11: false,
+ edge14: true,
+ chrome57: chrome.experimental,
+ chrome58: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ node8: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'async functions',
+ category: '2017 features',
+ significance: 'large',
+ spec: 'https://tc39.github.io/ecma262/#sec-async-function-definitions',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function',
+ subtests: [
+ {
+ // Should test that async functions return promises
+ // that (without await) resolve to the returned value.
+ name: 'return',
+ exec() {
+ /*
+ async function a() {
+ return "foo";
+ }
+ var p = a();
+ if (!(p instanceof Promise)) {
+ return false;
+ }
+ p.then(function (result) {
+ if (result === "foo") {
+ asyncTestPassed();
+ }
+ });
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome52: chrome.experimental,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'throw',
+ exec() {
+ /*
+ async function a() {
+ throw "foo";
+ }
+ var p = a();
+ if (!(p instanceof Promise)) {
+ return false;
+ }
+ p.catch (function (result) {
+ if (result === "foo") {
+ asyncTestPassed();
+ }
+ });
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ babel7corejs2: babel.regenerator,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'no line break between async and function',
+ exec() {
+ /*
+ async function a() {}
+ try { Function ("async\n function a() {await 0}")(); } catch (e) { return true; }
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ babel7corejs3: true,
+ closure: true,
+ typescript1corejs2: null,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: false,
+ edge14: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'no "prototype" property',
+ exec() {
+ /*
+ async function a() {};
+ return !a.hasOwnProperty("prototype");
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ closure: false,
+ typescript1corejs2: false,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'await',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/await',
+ exec() {
+ /*
+ (async function () {
+ await Promise.resolve();
+ var a1 = await new Promise(function (resolve) { setTimeout(resolve,800,"foo"); });
+ var a2 = await new Promise(function (resolve) { setTimeout(resolve,800,"bar"); });
+ if (a1 + a2 === "foobar") {
+ asyncTestPassed();
+ }
+ }());
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome52: chrome.experimental,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'await, rejection',
+ exec() {
+ /*
+ (async function () {
+ await Promise.resolve();
+ try {
+ var a1 = await new Promise(function (_, reject) { setTimeout(reject,800,"foo"); });
+ } catch (e) {
+ if (e === "foo") {
+ asyncTestPassed();
+ }
+ }
+ }());
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ babel7corejs2: babel.regenerator,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'must await a value',
+ exec() {
+ /*
+ async function a() { await Promise.resolve(); }
+ try { Function ("(async function a() { await; }())")(); } catch (e) { return true; }
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ babel7corejs3: true,
+ closure: true,
+ typescript1corejs2: null,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'can await non-Promise values',
+ exec() {
+ /*
+ (async function () {
+ await Promise.resolve();
+ var e = await "foo";
+ if (e === "foo") {
+ asyncTestPassed();
+ }
+ }());
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ babel7corejs2: babel.regenerator,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'cannot await in parameters',
+ exec() {
+ /*
+ async function a() { await Promise.resolve(); }
+ try { Function ("(async function a(b = await Promise.resolve()) {}())")(); } catch (e) { return true; }
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ babel7corejs3: true,
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: null,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'async methods, object literals',
+ exec() {
+ /*
+ var o = {
+ async a() { return await Promise.resolve("foo"); }
+ };
+ var p = o.a();
+ if (!(p instanceof Promise)) {
+ return false;
+ }
+ p.then(function (result) {
+ if (result === "foo") {
+ asyncTestPassed();
+ }
+ });
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ babel7corejs2: babel.regenerator,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'async methods, classes',
+ exec() {
+ /*
+ class C {
+ async a() { return await Promise.resolve("foo"); }
+ };
+ var p = new C().a();
+ if (!(p instanceof Promise)) {
+ return false;
+ }
+ p.then(function (result) {
+ if (result === "foo") {
+ asyncTestPassed();
+ }
+ });
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ babel7corejs2: babel.regenerator,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'async arrow functions in methods, classes',
+ exec() {
+ /*
+ function doSomething(callback) {
+ callback();
+ }
+ class C {
+ a() {
+ doSomething(async () => {
+ await 1;
+ asyncTestPassed();
+ });
+ }
+ };
+ var p = new C().a();
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome52: chrome.experimental,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10: false,
+ safari10_1: false,
+ safari11: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'async arrow functions',
+ exec() {
+ /*
+ var a = async () => await Promise.resolve("foo");
+ var p = a();
+ if (!(p instanceof Promise)) {
+ return false;
+ }
+ p.then(function (result) {
+ if (result === "foo") {
+ asyncTestPassed();
+ }
+ });
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome52: chrome.experimental,
+ chrome55: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'correct prototype chain',
+ exec() {
+ /*
+ var asyncFunctionProto = Object.getPrototypeOf(async function () {});
+ return asyncFunctionProto !== function () {}.prototype
+ && Object.getPrototypeOf(asyncFunctionProto) === Function.prototype;
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ closure: false,
+ typescript1corejs2: false,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: false,
+ edge14: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'async function prototype, Symbol.toStringTag',
+ exec() {
+ /*
+ return Object.getPrototypeOf(async function () {})[Symbol.toStringTag] === "AsyncFunction";
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ closure: false,
+ typescript1corejs2: false,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: false,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'async function constructor',
+ exec() {
+ /*
+ var a = async function () {}.constructor("return 'foo';");
+ var p = a();
+ if (!(p instanceof Promise)) {
+ return false;
+ }
+ p.then(function (result) {
+ if (result === "foo") {
+ asyncTestPassed();
+ }
+ });
+ */
+ },
+ res: {
+ tr: null,
+ babel6corejs2: null,
+ closure: false,
+ typescript1corejs2: false,
+ chrome52: null,
+ chrome55: true,
+ ie11: false,
+ edge13: false,
+ edge14: edge.experimental,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'shared memory and atomics',
+ category: '2017 features',
+ significance: 'medium',
+ subtests: [
+ {
+ name: 'SharedArrayBuffer',
+ spec: 'https://tc39.github.io/ecma262/#sec-sharedarraybuffer-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer',
+ exec() {
+ /*
+ return typeof SharedArrayBuffer === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: {
+ val: false,
+ note_id: 'edg-shared-memory-spectre',
+ note_html: 'The feature was temporarily disabled to mitigate the Meltdown and Spectre CPU bugs.',
+ },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: {
+ val: 'flagged',
+ note_id: 'fx-shared-memory-spectre',
+ note_html:
+ 'The feature was temporarily disabled to mitigate the Meltdown and Spectre CPU bugs. It can be enabled via javascript.options.shared_memory
setting under about:config
',
+ },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox77: {
+ val: false,
+ note_id: 'fx-shared-memory-esr-disable',
+ note_html: 'The feature was intentionally disabled to prepare for Firefox 78 ESR',
+ },
+ firefox79: {
+ val: true,
+ note_id: 'fx-shared-memory-cors-isolation',
+ note_html:
+ 'The feature is available with properly set CORS isolation headers or via enabling dom.postMessage.sharedArrayBuffer.bypassCOOP_COEP.insecure.enabled
setting under about:config
',
+ },
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: {
+ val: false,
+ note_id: 'chr-shared-memory-spectre',
+ note_html: 'The feature was temporarily disabled to mitigate the Meltdown and Spectre CPU bugs.',
+ },
+ chrome68: true,
+ safari10_1: true,
+ safari11: {
+ val: false,
+ note_id: 'sf-shared-memory-spectre',
+ note_html:
+ 'The feature was temporarily disabled to mitigate the Meltdown and Spectre CPU bugs.',
+ },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'SharedArrayBuffer[Symbol.species]',
+ exec() {
+ /*
+ return SharedArrayBuffer[Symbol.species] === SharedArrayBuffer;
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox52: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox77: { val: false, note_id: 'fx-shared-memory-esr-disable' },
+ firefox79: { val: true, note_id: 'fx-shared-memory-cors-isolation' },
+ opera10_50: false,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'SharedArrayBuffer.prototype.byteLength',
+ spec: 'https://tc39.github.io/ecma262/#sec-get-sharedarraybuffer.prototype.bytelength',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/byteLength',
+ exec() {
+ /*
+ return 'byteLength' in SharedArrayBuffer.prototype;
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox77: { val: false, note_id: 'fx-shared-memory-esr-disable' },
+ firefox79: { val: true, note_id: 'fx-shared-memory-cors-isolation' },
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari11: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'SharedArrayBuffer.prototype.slice',
+ spec: 'https://tc39.github.io/ecma262/#sec-sharedarraybuffer.prototype.slice',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer/slice',
+ exec() {
+ /*
+ return typeof SharedArrayBuffer.prototype.slice === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox52: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox77: { val: false, note_id: 'fx-shared-memory-esr-disable' },
+ firefox79: { val: true, note_id: 'fx-shared-memory-cors-isolation' },
+ opera10_50: false,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'SharedArrayBuffer.prototype[Symbol.toStringTag]',
+ spec: 'https://tc39.github.io/ecma262/#sec-sharedarraybuffer.prototype.toString',
+ exec() {
+ /*
+ return SharedArrayBuffer.prototype[Symbol.toStringTag] === 'SharedArrayBuffer';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox52: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox77: { val: false, note_id: 'fx-shared-memory-esr-disable' },
+ firefox79: { val: true, note_id: 'fx-shared-memory-cors-isolation' },
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.add',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.add',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/add',
+ exec() {
+ /*
+ return typeof Atomics.add === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.and',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.and',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/and',
+ exec() {
+ /*
+ return typeof Atomics.and === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.compareExchange',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.compareExchange',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/compareExchange',
+ exec() {
+ /*
+ return typeof Atomics.compareExchange === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.exchange',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.exchange',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/exchange',
+ exec() {
+ /*
+ return typeof Atomics.exchange === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.wait',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.wait',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/wait',
+ exec() {
+ /*
+ return typeof Atomics.wait === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox48: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.notify',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.notify',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/notify',
+ exec() {
+ /*
+ return typeof Atomics.notify === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox48: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: false,
+ graalvm20: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.isLockFree',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.isLockFree',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/isLockFree',
+ exec() {
+ /*
+ return typeof Atomics.isLockFree === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.load',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.load',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/load',
+ exec() {
+ /*
+ return typeof Atomics.load === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.or',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.or',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/or',
+ exec() {
+ /*
+ return typeof Atomics.or === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.store',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.store',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/store',
+ exec() {
+ /*
+ return typeof Atomics.store === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.sub',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.sub',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/sub',
+ exec() {
+ /*
+ return typeof Atomics.sub === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Atomics.xor',
+ spec: 'https://tc39.github.io/ecma262/#sec-atomics.xor',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Atomics/xor',
+ exec() {
+ /*
+ return typeof Atomics.xor === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ edge16: true,
+ edge17: { val: false, note_id: 'edg-shared-memory-spectre' },
+ firefox2: false,
+ firefox46: firefox.nightly,
+ firefox51: firefox.developer,
+ firefox53: firefox.sharedmem,
+ firefox55: true,
+ firefox57: { val: 'flagged', note_id: 'fx-shared-memory-spectre' },
+ firefox72: firefox.nightly,
+ firefox74: firefox.beta,
+ firefox78: true,
+ opera10_50: false,
+ chrome48: chrome.sharedmem,
+ chrome60: true,
+ chrome63: { val: false, note_id: 'chr-shared-memory-spectre' },
+ chrome68: true,
+ safari10_1: true,
+ safari11_1: { val: false, note_id: 'sf-shared-memory-spectre' },
+ safari15_2: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'generator functions can\'t be used with "new"',
+ category: '2016 misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/7.0/index.html#sec-createdynamicfunction',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*#Generators_are_not_constructable',
+ links: [
+ {
+ note_id: 'new-gen-fn',
+ note_html:
+ 'TC39 meeting notes from July 28, 2015.',
+ },
+ ],
+ exec() {
+ /*
+ function * generator() {
+ yield 3;
+ }
+ try {
+ new generator();
+ } catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox43: true,
+ opera10_50: false,
+ chrome50: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'generator throw() caught by inner generator',
+ category: '2016 misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/7.0/index.html#sec-generatorfunction-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*#IteratorResult_object_returned_instead_of_throwing',
+ links: [
+ {
+ note_id: 'gen-throw',
+ note_html:
+ '\'Semantics of yield* in throw case\' GitHub issue in ECMA-262 repo.',
+ },
+ ],
+ exec() {
+ /*
+ function * generator() {
+ yield * (function * () {
+ try {
+ yield 'foo';
+ }
+ catch (e) {
+ return;
+ }
+ }());
+ yield 'bar';
+ }
+ var iter = generator();
+ iter.next();
+ return iter['throw']().value === 'bar';
+ */
+ },
+ res: {
+ babel7corejs3: true,
+ closure: false,
+ closure20180319: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'strict fn w/ non-strict non-simple params is error',
+ category: '2016 misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/7.0/index.html#sec-functiondeclarationinstantiation',
+ links: [
+ {
+ note_id: 'strict-fn-non-strict-params',
+ note_html:
+ 'TC39 meeting notes from July 29, 2015.',
+ },
+ ],
+ exec() {
+ /*
+ function foo(...a) {}
+ try {
+ Function ("function bar(...a) {'use strict';}")();
+ } catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel7corejs3: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ chrome47: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'nested rest destructuring, declarations',
+ category: '2016 misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/7.0/index.html#sec-destructuring-assignment',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#Nested_object_and_array_destructuring',
+ links: [
+ {
+ note_id: 'nested-rest-destruct-decl',
+ note_html:
+ 'TC39 meeting notes from July 28, 2015.',
+ },
+ ],
+ exec() {
+ /*
+ var [x, ...[y, ...z]] = [1,2,3,4];
+ return x === 1 && y === 2 && z + '' === '3,4';
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox47: true,
+ opera10_50: false,
+ chrome49: true,
+ safari10_1: true,
+ typescript1corejs2: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'nested rest destructuring, parameters',
+ category: '2016 misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/7.0/index.html#sec-destructuring-assignment',
+ links: [
+ {
+ note_id: 'nested-rest-destruct-params',
+ note_html:
+ 'TC39 meeting notes from July 28, 2015.',
+ },
+ ],
+ exec() {
+ /*
+ return function ([x, ...[y, ...z]]) {
+ return x === 1 && y === 2 && z + '' === '3,4';
+ }([1,2,3,4]);
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox47: true,
+ opera10_50: false,
+ typescript1corejs2: true,
+ chrome49: true,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Proxy, "enumerate" handler removed',
+ category: '2016 misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/7.0/index.html#sec-proxy-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/enumerate',
+ links: [
+ {
+ note_id: 'proxy-enumerate-removed',
+ note_html:
+ '\'Normative: Remove [[Enumerate]] and associated reflective capabilities\' GitHub Pull Request in ECMA-262 repo.',
+ },
+ ],
+ exec() {
+ /*
+ var passed = true;
+ var proxy = new Proxy({}, {
+ enumerate: function () {
+ passed = false;
+ }
+ });
+ for (var key in proxy); // Should not throw, nor execute the 'enumerate' method.
+ return passed;
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox18: true,
+ firefox25: false,
+ firefox47: true,
+ opera10_50: false,
+ chrome50: true,
+ safari10: true,
+ duktape2_0: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Proxy internal calls, Array.prototype.includes',
+ category: '2016 misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/7.0/index.html#sec-array.prototype.includes',
+ exec() {
+ /*
+ // Array.prototype.includes -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({length: 3, 0: '', 1: '', 2: '', 3: ''}, { get: function (o, k) { get.push(k); return o[k]; }});
+ Array.prototype.includes.call(p, {});
+ if (get + '' !== "length,0,1,2") return;
+
+ get = [];
+ p = new Proxy({length: 4, 0: NaN, 1: '', 2: NaN, 3: ''}, { get: function (o, k) { get.push(k); return o[k]; }});
+ Array.prototype.includes.call(p, NaN, 1);
+ return (get + '' === "length,1,2");
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox43: true,
+ opera10_50: false,
+ chrome49: true,
+ ie11: false,
+ edge14: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Object.prototype getter/setter methods',
+ spec: 'https://tc39.github.io/ecma262/#sec-object.prototype.__defineGetter__',
+ category: '2017 annex b',
+ significance: 'tiny',
+ subtests: [
+ {
+ name: '__defineGetter__',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__defineGetter__',
+ exec() {
+ /*
+ var obj = {};
+ function bar() { return "bar"; }
+ Object.prototype.__defineGetter__.call(obj, "foo", bar);
+ var prop = Object.getOwnPropertyDescriptor(obj, "foo");
+ return prop.get === bar && !prop.writable && prop.configurable
+ && prop.enumerable;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox4: true,
+ opera10_50: false,
+ opera12: true,
+ chrome30: true,
+ node0_12: true,
+ safari4: true,
+ safari9: true,
+ android4_0: true,
+ ios5_1: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '__defineGetter__, symbols',
+ exec() {
+ /*
+ var obj = {};
+ var sym = Symbol();
+ function bar() { return "bar"; }
+ Object.prototype.__defineGetter__.call(obj, sym, bar);
+ var prop = Object.getOwnPropertyDescriptor(obj, sym);
+ return prop.get === bar && !prop.writable && prop.configurable
+ && prop.enumerable;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ safari9: true,
+ android4_0: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '__defineGetter__, ToObject(this)',
+ exec() {
+ /*
+ var key = '__accessors_test__';
+ __defineGetter__.call(1, key, function () {});
+ try {
+ __defineGetter__.call(null, key, function () {});
+ } catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge16: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ opera12: true,
+ chrome60: chrome.harmony,
+ chrome62: true,
+ safari5_1: true,
+ safari9: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '__defineSetter__',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__defineSetter__',
+ exec() {
+ /*
+ var obj = {};
+ function bar() {}
+ Object.prototype.__defineSetter__.call(obj, "foo", bar);
+ var prop = Object.getOwnPropertyDescriptor(obj, "foo");
+ return prop.set === bar && !prop.writable && prop.configurable
+ && prop.enumerable;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox4: true,
+ opera10_50: false,
+ opera12: true,
+ chrome30: true,
+ node0_12: true,
+ safari4: true,
+ safari9: true,
+ android4_0: true,
+ ios5_1: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '__defineSetter__, symbols',
+ exec() {
+ /*
+ var obj = {};
+ var sym = Symbol();
+ function bar(baz) {}
+ Object.prototype.__defineSetter__.call(obj, sym, bar);
+ var prop = Object.getOwnPropertyDescriptor(obj, sym);
+ return prop.set === bar && !prop.writable && prop.configurable
+ && prop.enumerable;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ safari9: true,
+ android4_0: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '__defineSetter__, ToObject(this)',
+ exec() {
+ /*
+ var key = '__accessors_test__';
+ __defineSetter__.call(1, key, function () {});
+ try {
+ __defineSetter__.call(null, key, function () {});
+ } catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge16: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ opera12: true,
+ chrome60: chrome.harmony,
+ chrome62: true,
+ safari5_1: true,
+ safari9: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '__lookupGetter__',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__lookupGetter__',
+ exec() {
+ /*
+ var obj = {
+ get foo() { return "bar"},
+ qux: 1
+ };
+ var foo = Object.prototype.__lookupGetter__.call(obj, "foo");
+ return foo() === "bar"
+ && Object.prototype.__lookupGetter__.call(obj, "qux") === void undefined
+ && Object.prototype.__lookupGetter__.call(obj, "baz") === void undefined;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: true,
+ opera10_50: true,
+ opera12: true,
+ chrome30: true,
+ node0_12: true,
+ safari3_1: true,
+ safari9: true,
+ android4_0: true,
+ ios5_1: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '__lookupGetter__, prototype chain',
+ exec() {
+ /*
+ var obj = {
+ get foo() { return "bar"},
+ qux: 1
+ };
+ var foo = Object.prototype.__lookupGetter__.call(Object.create(obj), "foo");
+ return foo() === "bar"
+ && Object.prototype.__lookupGetter__.call(obj, "qux") === void undefined
+ && Object.prototype.__lookupGetter__.call(obj, "baz") === void undefined;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox4: true,
+ opera10_50: false,
+ opera12: true,
+ chrome30: true,
+ node0_12: true,
+ safari4: true,
+ safari9: true,
+ android4_0: true,
+ ios5_1: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '__lookupGetter__, symbols',
+ exec() {
+ /*
+ var sym = Symbol();
+ var sym2 = Symbol();
+ var obj = {};
+ Object.defineProperty(obj, sym, { get: function () { return "bar"; }});
+ Object.defineProperty(obj, sym2, { value: 1 });
+ var foo = Object.prototype.__lookupGetter__.call(obj, sym);
+ return foo() === "bar"
+ && Object.prototype.__lookupGetter__.call(obj, sym2) === void undefined
+ && Object.prototype.__lookupGetter__.call(obj, Symbol()) === void undefined;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ safari9: true,
+ android4_0: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '__lookupGetter__, ToObject(this)',
+ exec() {
+ /*
+ __lookupGetter__.call(1, 'key');
+ try {
+ __lookupGetter__.call(null, 'key');
+ } catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox24: true,
+ opera10_50: false,
+ opera12: true,
+ chrome60: chrome.harmony,
+ chrome62: true,
+ safari5_1: true,
+ safari9: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '__lookupGetter__, data properties can shadow accessors',
+ exec() {
+ /*
+ var a = {};
+ var b = Object.create(a);
+ b.foo = 1;
+ a.__defineGetter__("foo", function () {});
+ return b.__lookupGetter__("foo") === void undefined;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox4: true,
+ opera10_50: false,
+ opera12: true,
+ chrome57: true,
+ node8: true,
+ safari4: true,
+ safari9: true,
+ ios5_1: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '__lookupSetter__',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/__lookupSetter__',
+ exec() {
+ /*
+ var obj = {
+ set foo(baz) { return "bar"; },
+ qux: 1
+ };
+ var foo = Object.prototype.__lookupSetter__.call(obj, "foo");
+ return foo() === "bar"
+ && Object.prototype.__lookupSetter__.call(obj, "qux") === void undefined
+ && Object.prototype.__lookupSetter__.call(obj, "baz") === void undefined;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: true,
+ opera10_50: true,
+ opera12: true,
+ chrome30: true,
+ node0_12: true,
+ safari3_1: true,
+ safari9: true,
+ android4_0: true,
+ ios5_1: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '__lookupSetter__, prototype chain',
+ exec() {
+ /*
+ var obj = {
+ set foo(baz) { return "bar"; },
+ qux: 1
+ };
+ var foo = Object.prototype.__lookupSetter__.call(Object.create(obj), "foo");
+ return foo() === "bar"
+ && Object.prototype.__lookupSetter__.call(obj, "qux") === void undefined
+ && Object.prototype.__lookupSetter__.call(obj, "baz") === void undefined;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox4: true,
+ opera10_50: false,
+ opera12: true,
+ chrome30: true,
+ node0_12: true,
+ safari4: true,
+ safari9: true,
+ android4_0: true,
+ ios5_1: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '__lookupSetter__, symbols',
+ exec() {
+ /*
+ var sym = Symbol();
+ var sym2 = Symbol();
+ var obj = {};
+ Object.defineProperty(obj, sym, { set: function (baz) { return "bar"; }});
+ Object.defineProperty(obj, sym2, { value: 1 });
+ var foo = Object.prototype.__lookupSetter__.call(obj, sym);
+ return foo() === "bar"
+ && Object.prototype.__lookupSetter__.call(obj, sym2) === void undefined
+ && Object.prototype.__lookupSetter__.call(obj, Symbol()) === void undefined;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ safari9: true,
+ android4_0: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '__lookupSetter__, ToObject(this)',
+ exec() {
+ /*
+ __lookupSetter__.call(1, 'key');
+ try {
+ __lookupSetter__.call(null, 'key');
+ } catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox24: true,
+ opera10_50: false,
+ opera12: true,
+ chrome60: chrome.harmony,
+ chrome62: true,
+ safari5_1: true,
+ safari9: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '__lookupSetter__, data properties can shadow accessors',
+ exec() {
+ /*
+ var a = {};
+ var b = Object.create(a);
+ b.foo = 1;
+ a.__defineSetter__("foo", function () {})
+ return b.__lookupSetter__("foo") === void undefined
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox4: true,
+ opera10_50: false,
+ opera12: true,
+ chrome57: true,
+ node8: true,
+ safari4: true,
+ safari9: true,
+ ios5_1: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Proxy internal calls, getter/setter methods',
+ spec: 'https://tc39.github.io/ecma262/#sec-object.prototype.__defineGetter__',
+ category: '2017 annex b',
+ significance: 'tiny',
+ subtests: [
+ {
+ name: '__defineGetter__',
+ exec() {
+ /*
+ // Object.prototype.__defineGetter__ -> DefinePropertyOrThrow -> [[DefineOwnProperty]]
+ var def = [];
+ var p = new Proxy({}, {
+ defineProperty: function (o, v, desc) {
+ def.push(v);
+ Object.defineProperty(o, v, desc);
+ return true;
+ }
+ });
+ Object.prototype.__defineGetter__.call(p, "foo", Object);
+ return def + '' === "foo";
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ chrome52: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '__defineSetter__',
+ exec() {
+ /*
+ // Object.prototype.__defineSetter__ -> DefinePropertyOrThrow -> [[DefineOwnProperty]]
+ var def = [];
+ var p = new Proxy({}, {
+ defineProperty: function (o, v, desc) {
+ def.push(v);
+ Object.defineProperty(o, v, desc);
+ return true;
+ }
+ });
+ Object.prototype.__defineSetter__.call(p, "foo", Object);
+ return def + '' === "foo";
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ chrome52: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '__lookupGetter__',
+ exec() {
+ /*
+ // Object.prototype.__lookupGetter__ -> [[GetOwnProperty]]
+ // Object.prototype.__lookupGetter__ -> [[GetPrototypeOf]]
+ var gopd = [];
+ var gpo = false;
+ var p = new Proxy({}, {
+ getPrototypeOf: function (o) {
+ gpo = true;
+ return Object.getPrototypeOf(o);
+ },
+ getOwnPropertyDescriptor: function (o, v) {
+ gopd.push(v);
+ return Object.getOwnPropertyDescriptor(o, v);
+ }
+ });
+ Object.prototype.__lookupGetter__.call(p, "foo");
+ return gopd + '' === "foo" && gpo;
+ */
+ },
+ res: {
+ ie11: false,
+ edge14: true,
+ chrome57: true,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ node8: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '__lookupSetter__',
+ exec() {
+ /*
+ // Object.prototype.__lookupSetter__ -> [[GetOwnProperty]]
+ // Object.prototype.__lookupSetter__ -> [[GetPrototypeOf]]
+ var gopd = [];
+ var gpo = false;
+ var p = new Proxy({}, {
+ getPrototypeOf: function (o) {
+ gpo = true;
+ return Object.getPrototypeOf(o);
+ },
+ getOwnPropertyDescriptor: function (o, v) {
+ gopd.push(v);
+ return Object.getOwnPropertyDescriptor(o, v);
+ }
+ });
+ Object.prototype.__lookupSetter__.call(p, "foo");
+ return gopd + '' === "foo" && gpo;
+ */
+ },
+ res: {
+ ie11: false,
+ edge14: true,
+ chrome57: true,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ node8: true,
+ safari10: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Proxy "ownKeys" handler, duplicate keys for non-extensible targets',
+ category: '2018 misc',
+ significance: 'tiny',
+ spec: 'https://tc39.es/ecma262/#sec-proxy-object-internal-methods-and-internal-slots-ownpropertykeys',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys',
+ exec() {
+ /*
+ var p = new Proxy({}, {
+ ownKeys() {
+ return ["a", "a"];
+ }
+ });
+ try {
+ Object.keys(p);
+ } catch (e) {
+ return e instanceof TypeError;
+ }
+ return false;
+ */
+ },
+ res: {
+ ie11: false,
+ edge16: false,
+ chrome75: true,
+ firefox57: true,
+ firefox70: true,
+ safari13: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: false,
+ graalvm20: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp "u" flag, case folding',
+ category: '2017 misc',
+ significance: 'tiny',
+ spec: 'https://github.com/tc39/ecma262/pull/525',
+ exec() {
+ /*
+ return "ſ".match(/\w/iu) && !"ſ".match(/\W/iu)
+ && "\u212a".match(/\w/iu) && !"\u212a".match(/\W/iu)
+ && "\u212a".match(/.\b/iu) && "ſ".match(/.\b/iu)
+ && !"\u212a".match(/.\B/iu) && !"ſ".match(/.\B/iu);
+ */
+ },
+ res: {
+ ie11: false,
+ firefox2: false,
+ firefox54: true,
+ opera10_50: false,
+ chrome59: true,
+ safari10: true,
+ safari10_1: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'assignments allowed in for-in head in non-strict mode',
+ spec: 'https://tc39.github.io/ecma262/#sec-initializers-in-forin-statement-heads',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...in#Compatibility_Initializer_expressions_in_strict_mode',
+ category: '2017 annex b',
+ significance: 'tiny',
+ exec() {
+ /*
+ for (var i = 0 in {}) {}
+ return i === 0;
+ */
+ },
+ res: {
+ tr: true,
+ babel7corejs3: true,
+ ie10: true,
+ edge12: true,
+ firefox2: true,
+ firefox31: true,
+ firefox40: false,
+ firefox52: true,
+ opera10_50: true,
+ chrome30: true,
+ safari3_1: true,
+ safari9: false,
+ safari10_1: true,
+ node0_12: true,
+ android4_0: true,
+ ios5_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: false,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'arguments.caller removed',
+ category: '2017 misc',
+ significance: 'tiny',
+ spec: 'https://github.com/tc39/ecma262/pull/689',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/arguments/caller',
+ exec() {
+ /*
+ return (function () {
+ 'use strict';
+ return !Object.getOwnPropertyDescriptor(arguments, 'caller');
+ })();
+ */
+ },
+ res: {
+ ie11: false,
+ edge16: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome56: true,
+ node8: true,
+ safari10_1: true,
+ duktape2_0: false,
+ duktape2_4: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'object rest/spread properties',
+ significance: 'medium',
+ category: '2018 features',
+ spec: 'https://github.com/tc39/proposal-object-rest-spread',
+ subtests: [
+ {
+ name: 'object rest properties',
+ exec() {
+ /*
+ var { a, ...rest } = { a: 1, b: 2, c: 3 };
+ return a === 1 && rest.a === void undefined && rest.b === 2 && rest.c === 3;
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ closure20181028: {
+ val: false,
+ note_id: 'closure-object-assign',
+ note_html: 'Requires native support for Object.assign
',
+ },
+ closure20210906: true,
+ typescript2_1corejs2: true,
+ jsx: true,
+ ie11: false,
+ firefox2: false,
+ firefox55: true,
+ opera10_50: false,
+ chrome58: chrome.experimental,
+ chrome60: true,
+ safari11: false,
+ safari11_1: true,
+ safaritp: true,
+ webkit: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'object spread properties',
+ exec() {
+ /*
+ var spread = { b: 2, c: 3 };
+ var O = { a: 1, ...spread };
+ return O !== spread && (O.a + O.b + O.c) === 6;
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ closure20190121: {
+ val: false,
+ note_id: 'closure-object-assign',
+ },
+ closure20210906: true,
+ jsx: true,
+ ie11: false,
+ firefox2: false,
+ firefox55: true,
+ opera10_50: false,
+ chrome58: chrome.experimental,
+ chrome60: true,
+ typescript2_1corejs2: true,
+ safari11: false,
+ safari11_1: true,
+ safaritp: true,
+ webkit: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Promise.prototype.finally',
+ category: '2018 features',
+ significance: 'medium',
+ spec: 'https://github.com/tc39/proposal-promise-finally',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/finally',
+ subtests: [
+ {
+ name: 'basic support',
+ exec() {
+ /*
+ var p1 = Promise.resolve("foo");
+ var p2 = Promise.reject("bar");
+ var score = 0;
+ function thenFn(result) {
+ score += (result === "foo");
+ check();
+ }
+ function catchFn(result) {
+ score += (result === "bar");
+ check();
+ }
+ function finallyFn() {
+ score += (arguments.length === 0);
+ check();
+ }
+ p1.then(thenFn);
+ p1.finally(finallyFn);
+ p1.finally(function () {
+ // should return a new Promise
+ score += p1.finally() !== p1;
+ check();
+ });
+ p2.catch (catchFn);
+ p2.finally(finallyFn);
+ function check() {
+ if (score === 5) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20180402: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge18: true,
+ firefox2: false,
+ firefox57: false,
+ firefox58: true,
+ opera10_50: false,
+ chrome61: chrome.promise,
+ chrome63: true,
+ safari11_1: true,
+ safaritp: true,
+ webkit: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: "don't change resolution value",
+ exec() {
+ /*
+ var score = 0;
+ function thenFn(result) {
+ score += (result === "foo");
+ check();
+ }
+ function catchFn(result) {
+ score += (result === "bar");
+ check();
+ }
+ function finallyFn() {
+ score++;
+ check();
+ return Promise.resolve("foobar");
+ }
+ Promise.resolve("foo").finally(finallyFn).then(thenFn);
+ Promise.reject("bar").finally(finallyFn).catch(catchFn);
+ function check() {
+ if (score === 4) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20180402: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge18: true,
+ firefox2: false,
+ firefox57: false,
+ firefox58: true,
+ opera10_50: false,
+ chrome61: chrome.promise,
+ chrome63: true,
+ safari11_1: true,
+ safaritp: true,
+ webkit: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'change rejection value',
+ exec() {
+ /*
+ var score = 0;
+ Promise
+ .reject("foobar")
+ .finally(function () {
+ return Promise.reject("foo");
+ })
+ .catch (function (result) {
+ score += (result === "foo");
+ check();
+ return Promise.reject("foobar");
+ })
+ .finally(function () {
+ throw new Error('bar');
+ })
+ .catch (function (result) {
+ score += (result.message === "bar");
+ check();
+ });
+ function check() {
+ if (score === 2) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20180402: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge18: true,
+ firefox2: false,
+ firefox57: false,
+ firefox58: true,
+ opera10_50: false,
+ safari11_1: true,
+ safaritp: true,
+ chrome61: chrome.promise,
+ chrome63: true,
+ webkit: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'template literal revision',
+ spec: 'https://github.com/tc39/proposal-template-literal-revision',
+ category: '2018 misc',
+ significance: 'small',
+ exec() {
+ /*
+ function tag(strings, a) {
+ return strings[0] === void undefined
+ && strings.raw[0] === "\\01\\1\\xg\\xAg\\u0\\u0g\\u00g\\u000g\\u{g\\u{0\\u{110000}"
+ && strings[1] === "\0"
+ && strings.raw[1] === "\\0"
+ && a === 0;
+ }
+ return tag`\01\1\xg\xAg\u0\u0g\u00g\u000g\u{g\u{0\u{110000}${0}\0`;
+ */
+ },
+ res: {
+ babel7corejs3: true,
+ closure: false,
+ closure20181008: true,
+ closure20200315: false,
+ closure20200517: true,
+ ie11: false,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome59: chrome.harmony,
+ chrome62: true,
+ safari11: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 's (dotAll) flag for regular expressions',
+ spec: 'https://tc39.github.io/ecma262/#sec-get-regexp.prototype.dotAll',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll',
+ category: '2018 features',
+ significance: 'small',
+ exec() {
+ /*
+ const regex = /foo.bar/s;
+ return regex.test('foo\nbar');
+ */
+ },
+ res: {
+ es6tr: null,
+ tr: null,
+ babel6corejs2: true,
+ closure: false,
+ jsx: null,
+ typescript1corejs2: null,
+ es6shim: null,
+ konq4_14: null,
+ ie7: null,
+ ie10: false,
+ firefox1: null,
+ firefox2: false,
+ firefox77: false,
+ firefox78: true,
+ opera10_50: false,
+ chrome1: null,
+ chrome60: chrome.harmony,
+ chrome62: true,
+ safari11_1: true,
+ safaritp: true,
+ webkit: true,
+ xs6: null,
+ jxa: null,
+ node0_10: null,
+ duktape2_0: false,
+ duktape2_2: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ android1_5: null,
+ ios4: null,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'RegExp named capture groups',
+ spec: 'https://github.com/tc39/proposal-regexp-named-groups',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Groups_and_Ranges',
+ category: '2018 features',
+ significance: 'small',
+ exec() {
+ /*
+ var result = /(?\d{4})-(?\d{2})-(?\d{2})/.exec('2016-03-11');
+ return result.groups.year === '2016'
+ && result.groups.month === '03'
+ && result.groups.day === '11'
+ && result[0] === '2016-03-11'
+ && result[1] === '2016'
+ && result[2] === '03'
+ && result[3] === '11';
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox77: false,
+ firefox78: true,
+ opera10_50: false,
+ chrome60: chrome.harmony,
+ chrome64: true,
+ safari11_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp Lookbehind Assertions',
+ spec: 'https://github.com/tc39/proposal-regexp-lookbehind',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions/Assertions',
+ category: '2018 features',
+ significance: 'small',
+ exec() {
+ /*
+ return /(?<=a)b/.test('ab') && /(? b';
+ return eval('(' + str + ')') + '' === str;
+ */
+ },
+ res: {
+ node4: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome50: true,
+ safari10: true,
+ ie11: false,
+ edge13: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '[native code]',
+ exec() {
+ /*
+ const NATIVE_EVAL_RE = /\bfunction\b[\s\S]*\beval\b[\s\S]*\([\s\S]*\)[\s\S]*\{[\s\S]*\[[\s\S]*\bnative\b[\s\S]+\bcode\b[\s\S]*\][\s\S]*\}/;
+ return NATIVE_EVAL_RE.test(eval + '');
+ */
+ },
+ res: {
+ node4: true,
+ firefox2: false,
+ firefox10: true,
+ firefox45: true,
+ opera10_50: true,
+ chrome50: true,
+ safari3_1: true,
+ ie11: true,
+ edge13: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'class expression with implicit constructor',
+ exec() {
+ /*
+ var str = 'class A {}';
+ return eval('(' + str + ')') + '' === str;
+ */
+ },
+ res: {
+ node4: true,
+ firefox2: false,
+ firefox55: true,
+ opera10_50: false,
+ chrome50: true,
+ safari10: true,
+ ie11: false,
+ edge14: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'class expression with explicit constructor',
+ exec() {
+ /*
+ var str = 'class /\x2A a \x2A/ A /\x2A b \x2A/ extends /\x2A c \x2A/ function B() {} /\x2A d \x2A/ { /\x2A e \x2A/ constructor /\x2A f \x2A/ ( /\x2A g \x2A/ ) /\x2A h \x2A/ { /\x2A i \x2A/ ; /\x2A j \x2A/ } /\x2A k \x2A/ m /\x2A l \x2A/ ( /\x2A m \x2A/ ) /\x2A n \x2A/ { /\x2A o \x2A/ } /\x2A p \x2A/ }';
+ return eval('(/\x2A before \x2A/' + str + '/\x2A after \x2A/)') + '' === str;
+ */
+ },
+ res: {
+ node4: true,
+ firefox2: false,
+ firefox55: true,
+ opera10_50: false,
+ chrome50: true,
+ safari10: true,
+ ie11: false,
+ edge14: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'unicode escape sequences in identifiers',
+ exec() {
+ /*
+ var str = 'function \\u0061(\\u{62}, \\u0063) { \\u0062 = \\u{00063}; return b; }';
+ return eval('(/\x2A before \x2A/' + str + '/\x2A after \x2A/)') + '' === str;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox2: false,
+ firefox54: true,
+ opera10_50: false,
+ chrome59: chrome.harmony,
+ chrome66: true,
+ safari17: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'methods and computed property names',
+ exec() {
+ /*
+ var str = '[ /\x2A a \x2A/ "f" /\x2A b \x2A/ ] /\x2A c \x2A/ ( /\x2A d \x2A/ ) /\x2A e \x2A/ { /\x2A f \x2A/ }';
+ return eval('({ /\x2A before \x2A/' + str + '/\x2A after \x2A/ }.f)') + '' === str;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox2: false,
+ firefox54: true,
+ opera10_50: false,
+ chrome59: chrome.harmony,
+ chrome66: true,
+ safari17: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'JSON superset',
+ spec: 'https://github.com/tc39/proposal-json-superset',
+ category: '2019 misc',
+ significance: 'small',
+ subtests: [
+ {
+ name: 'LINE SEPARATOR can appear in string literals',
+ exec() {
+ /*
+ return eval("'\u2028'") === "\u2028";
+ */
+ },
+ res: {
+ closure: false,
+ closure20190215: true,
+ babel7corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox61: false,
+ firefox62: true,
+ chrome65: false,
+ chrome66: true,
+ safari11: false,
+ safari12: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'PARAGRAPH SEPARATOR can appear in string literals',
+ exec() {
+ /*
+ return eval("'\u2029'") === "\u2029";
+ */
+ },
+ res: {
+ closure: false,
+ closure20190215: true,
+ babel7corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox61: false,
+ firefox62: true,
+ chrome65: false,
+ chrome66: true,
+ safari11: false,
+ safari12: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Object.fromEntries',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-object-from-entries',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/fromEntries',
+ category: '2019 features',
+ exec() {
+ /*
+ var object = Object.fromEntries(new Map([['foo', 42], ['bar', 23]]));
+ return object.foo === 42 && object.bar === 23;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ closure: false,
+ closure20190325: true,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox52: false,
+ firefox62: false,
+ firefox63: true,
+ safari12_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ chrome73: true,
+ chrome74: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Well-formed JSON.stringify',
+ spec: 'https://github.com/tc39/proposal-well-formed-stringify',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify#Well-formed_JSON.stringify()',
+ category: '2019 misc',
+ significance: 'small',
+ exec() {
+ /*
+ return JSON.stringify('\uDF06\uD834') === "\"\\udf06\\ud834\""
+ && JSON.stringify('\uDEAD') === "\"\\udead\"";
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ edge16: false,
+ firefox10: false,
+ firefox52: false,
+ firefox63: false,
+ firefox64: true,
+ chrome70: false,
+ chrome71: false,
+ chrome72: true,
+ safari1: false,
+ safari12_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'string trimming',
+ category: '2019 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-string-left-right-trim',
+ subtests: [
+ {
+ name: 'String.prototype.trimLeft',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/TrimLeft',
+ exec() {
+ /*
+ return ' \t \n abc \t\n'.trimLeft() === 'abc \t\n';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20190709: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox3_5: true,
+ firefox3_6: true,
+ firefox4: true,
+ chrome7: true,
+ opera10_10: false,
+ konq4_4: false,
+ konq4_9: true,
+ besen: false,
+ phantom1_9: true,
+ node0_12: true,
+ safari3: false,
+ safari4: true,
+ safari12: true,
+ webkit: true,
+ es7shim: true,
+ android4_0: true,
+ ios5_1: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.trimRight',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/TrimRight',
+ exec() {
+ /*
+ return ' \t \n abc \t\n'.trimRight() === ' \t \n abc';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20190709: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox3_5: true,
+ firefox3_6: true,
+ firefox4: true,
+ chrome7: true,
+ opera10_10: false,
+ konq4_4: false,
+ konq4_9: true,
+ besen: false,
+ phantom1_9: true,
+ node0_12: true,
+ safari3: false,
+ safari4: true,
+ safari12: true,
+ webkit: true,
+ es7shim: true,
+ android4_0: true,
+ ios5_1: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.trimStart',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimStart',
+ exec() {
+ /*
+ return ' \t \n abc \t\n'.trimStart() === 'abc \t\n';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20190325: {
+ val: false,
+ note_id: 'closure-string-trimstart',
+ note_html: 'Requires native support for String.prototype.trimLeft.',
+ },
+ closure20190709: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox59: false,
+ firefox60: firefox.nightly,
+ firefox61: true,
+ chrome66: true,
+ opera10_50: false,
+ safari12: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.trimEnd',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/trimEnd',
+ exec() {
+ /*
+ return ' \t \n abc \t\n'.trimEnd() === ' \t \n abc';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20190325: {
+ val: false,
+ note_id: 'closure-string-trimend',
+ note_html: 'Requires native support for String.prototype.trimRight.',
+ },
+ closure20190709: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox59: false,
+ firefox60: firefox.nightly,
+ firefox61: true,
+ chrome66: true,
+ opera10_50: false,
+ safari12: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Array.prototype.{flat, flatMap}',
+ category: '2019 features',
+ significance: 'medium',
+ spec: 'https://tc39.github.io/proposal-flatMap/',
+ links: [
+ {
+ note_id: 'flatten-compat-issue',
+ note_html:
+ 'Name of Array.prototype.flatten()
changed to Array.prototype.flat()
due to web compatibility issues.',
+ },
+ ],
+ subtests: [
+ {
+ name: 'Array.prototype.flat',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flat',
+ exec() {
+ /*
+ return [1, [2, 3], [4, [5, 6]]].flat().join('') === '12345,6';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ closure: false,
+ closure20190301: true,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox58: false,
+ firefox59: {
+ val: false,
+ note_id: 'ffox-flatten',
+ note_html:
+ 'Older Firefox Nightly builds support only the obsolete draft function name Array.prototype.flatten()
.',
+ },
+ firefox62: true,
+ chrome69: true,
+ opera10_50: false,
+ safari12: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Array.prototype.flatMap',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/flatMap',
+ exec() {
+ /*
+ return [{a: 1, b: 2}, {a: 3, b: 4}].flatMap(function (it) {
+ return [it.a, it.b];
+ }).join('') === '1234';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20190301: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox58: false,
+ firefox59: firefox.nightly,
+ firefox62: true,
+ chrome69: true,
+ opera10_50: false,
+ safari12: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'flat and flatMap in Array.prototype[@@unscopables]',
+ exec() {
+ /*
+ return Array.prototype[Symbol.unscopables].flat
+ && Array.prototype[Symbol.unscopables].flatMap;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox58: false,
+ firefox59: false,
+ firefox62: false,
+ firefox67: true,
+ chrome69: false,
+ chrome73: true,
+ chrome74: true,
+ opera10_50: false,
+ safari12: false,
+ safari13: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'String.prototype.matchAll',
+ category: '2020 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/String.prototype.matchAll',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/matchAll',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ var iterator = '11a2bb'.matchAll(/(\d)(\D)/g);
+ if(iterator[Symbol.iterator]() !== iterator)return false;
+ var a = '', b = '', c = '', step;
+ while(!(step = iterator.next()).done) {
+ a += step.value[0];
+ b += step.value[1];
+ c += step.value[2];
+ }
+ return a === '1a2b'
+ && b === '12'
+ && c === 'ab';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: false,
+ closure20200101: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox65: false,
+ firefox66: firefox.nightly,
+ firefox67: true,
+ chrome67: false,
+ chrome68: chrome.harmony,
+ chrome73: true,
+ chrome74: true,
+ opera10_50: false,
+ safari13: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'throws on non-global regex',
+ exec() {
+ /*
+ if (typeof String.prototype.matchAll !== 'function') return false;
+ try {
+ '11a2bb'.matchAll(/(\d)(\D)/);
+ } catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ closure: false,
+ closure20200101: true,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox60: false,
+ firefox72: false,
+ firefox73: true,
+ chrome67: false,
+ chrome68: false,
+ chrome73: false,
+ chrome74: false,
+ chrome80: true,
+ opera10_50: false,
+ safari13: false,
+ safari13_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: false,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'BigInt',
+ category: '2020 features',
+ significance: 'medium',
+ spec: 'https://github.com/tc39/proposal-bigint',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/BigInt',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ return (1n + 2n) === 3n;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox10: false,
+ firefox45: false,
+ firefox66: false,
+ firefox67: firefox.bigint,
+ firefox68: true,
+ chrome67: true,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'constructor',
+ exec() {
+ /*
+ return BigInt("3") === 3n;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox10: false,
+ firefox45: false,
+ firefox66: false,
+ firefox67: firefox.bigint,
+ firefox68: true,
+ chrome67: true,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'BigInt.asUintN',
+ exec() {
+ /*
+ return typeof BigInt.asUintN === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ firefox10: false,
+ firefox45: false,
+ firefox66: false,
+ firefox67: firefox.bigint,
+ firefox68: true,
+ chrome67: true,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'BigInt.asIntN',
+ exec() {
+ /*
+ return typeof BigInt.asIntN === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ firefox10: false,
+ firefox45: false,
+ firefox66: false,
+ firefox67: firefox.bigint,
+ firefox68: true,
+ chrome67: true,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'BigInt64Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new BigInt64Array(buffer);
+ view[0] = 0x8000000000000000n;
+ return view[0] === -0x8000000000000000n;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox10: false,
+ firefox45: false,
+ firefox67: false,
+ firefox68: true,
+ chrome67: true,
+ safari15: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'BigUint64Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new BigUint64Array(buffer);
+ view[0] = 0x10000000000000000n;
+ return view[0] === 0n;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox10: false,
+ firefox45: false,
+ firefox67: false,
+ firefox68: true,
+ chrome67: true,
+ safari15: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'DataView.prototype.getBigInt64',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setBigInt64(0, 1n);
+ return view.getBigInt64(0) === 1n;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox10: false,
+ firefox45: false,
+ firefox66: false,
+ firefox67: firefox.bigint,
+ firefox68: true,
+ chrome67: true,
+ safari15: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'DataView.prototype.getBigUint64',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setBigUint64(0, 1n);
+ return view.getBigUint64(0) === 1n;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox10: false,
+ firefox45: false,
+ firefox66: false,
+ firefox67: firefox.bigint,
+ firefox68: true,
+ chrome67: true,
+ safari15: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Promise.allSettled',
+ category: '2020 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-promise-allSettled',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/allSettled',
+ exec() {
+ /*
+ Promise.allSettled([
+ Promise.resolve(1),
+ Promise.reject(2),
+ Promise.resolve(3)
+ ]).then(it => {
+ if (
+ it.length === 3 &&
+ it[0].status === 'fulfilled' && it[0].value === 1 &&
+ it[1].status === 'rejected' && it[1].reason === 2 &&
+ it[2].status === 'fulfilled' && it[2].value === 3
+ ) asyncTestPassed();
+ });
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ closure: false,
+ closure20191027: true,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox68: firefox.nightly,
+ firefox71: true,
+ chrome76: true,
+ safari13: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: false,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'globalThis',
+ category: '2020 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-global',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/globalThis',
+ subtests: [
+ {
+ name: '"globalThis" global property is global object',
+ exec() {
+ /*
+ var actualGlobal = Function ('return this')();
+ actualGlobal.__system_global_test__ = 42;
+ return typeof globalThis === 'object' && globalThis && globalThis === actualGlobal && !globalThis.lacksGlobalThis && globalThis.__system_global_test__ === 42;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ closure: false,
+ closure20200101: true,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox53: false,
+ firefox65: true,
+ chrome70: chrome.experimental,
+ chrome71: true,
+ opera10_50: false,
+ safari10_1: false,
+ safari12_1: true,
+ safaritp: true,
+ node0_10: false,
+ node0_12: false,
+ node4: false,
+ node6: false,
+ node6_5: false,
+ node7: false,
+ node7_6: false,
+ node8: false,
+ node8_3: false,
+ node8_7: false,
+ duktape2_0: false,
+ duktape2_5: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: '"globalThis" global property has correct property descriptor',
+ exec() {
+ /*
+ var actualGlobal = Function ('return this')();
+ if (typeof globalThis !== 'object') { return false; }
+ if (!('globalThis' in actualGlobal)) { return false; }
+ if (Object.prototype.propertyIsEnumerable.call(actualGlobal, 'globalThis')) { return false; }
+
+ var descriptor = Object.getOwnPropertyDescriptor(actualGlobal, 'globalThis');
+ return descriptor.value === actualGlobal && !descriptor.enumerable && descriptor.configurable && descriptor.writable;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ closure: false,
+ closure20200101: true,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox53: false,
+ firefox65: true,
+ chrome70: chrome.experimental,
+ chrome71: true,
+ opera10_50: false,
+ safari10_1: false,
+ safari12_1: true,
+ safaritp: true,
+ node0_10: false,
+ node0_12: false,
+ node4: false,
+ node6: false,
+ node6_5: false,
+ node7: false,
+ node7_6: false,
+ node8: false,
+ node8_3: false,
+ node8_7: false,
+ duktape2_0: false,
+ duktape2_5: true,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'optional chaining operator (?.)',
+ spec: 'https://github.com/tc39/proposal-optional-chaining',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining',
+ category: '2020 features',
+ significance: 'medium',
+ subtests: [
+ {
+ name: 'optional property access',
+ exec() {
+ /*
+ var foo = { baz: 42 };
+ var bar = null;
+ return foo?.baz === 42 && bar?.baz === void undefined;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20200927: true,
+ typescript3_7corejs3: true,
+ ie11: false,
+ firefox10: false,
+ firefox52: false,
+ firefox73: false,
+ firefox74: true,
+ chrome77: false,
+ chrome78: {
+ val: 'flagged',
+ note_id: 'chrome-optional-chaining',
+ note_html: 'The feature has to be enabled via --js-flags="--harmony-optional-chaining"
flag',
+ },
+ chrome80: true,
+ safari13_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: false,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'optional bracket access',
+ exec() {
+ /*
+ var foo = { baz: 42 };
+ var bar = null;
+ return foo?.['baz'] === 42 && bar?.['baz'] === void undefined;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20200927: true,
+ typescript3_7corejs3: true,
+ ie11: false,
+ firefox10: false,
+ firefox52: false,
+ firefox73: false,
+ firefox74: true,
+ chrome77: false,
+ chrome78: { val: 'flagged', note_id: 'chrome-optional-chaining' },
+ chrome80: true,
+ safari13_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: false,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'optional method call',
+ exec() {
+ /*
+ var foo = { baz: function () { return this.value; }, value: 42 };
+ var bar = null;
+ return foo?.baz() === 42 && bar?.baz() === void undefined;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20200927: true,
+ typescript3_7corejs3: true,
+ ie11: false,
+ firefox10: false,
+ firefox52: false,
+ firefox73: false,
+ firefox74: true,
+ chrome77: false,
+ chrome78: { val: 'flagged', note_id: 'chrome-optional-chaining' },
+ chrome80: true,
+ safari13_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: false,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'optional function call',
+ exec() {
+ /*
+ var foo = { baz: function () { return 42; } };
+ var bar = {};
+ function baz() { return 42; };
+ var n;
+ return foo.baz?.() === 42 && bar.baz?.() === void undefined && baz?.() === 42 && n?.() === void undefined;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20200927: true,
+ typescript3_7corejs3: true,
+ ie11: false,
+ firefox10: false,
+ firefox52: false,
+ firefox73: false,
+ firefox74: true,
+ chrome77: false,
+ chrome78: { val: 'flagged', note_id: 'chrome-optional-chaining' },
+ chrome80: true,
+ safari13_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: false,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'spread parameters after optional chaining',
+ exec() {
+ /*
+ var fn = null;
+ var n = null;
+ var o = {};
+
+ return fn?.(...[], 1) === void undefined && fn?.(...[], ...[]) === void undefined && o.method?.(...[], 1) === void undefined && n?.method(...[], 1) === void undefined;
+ */
+ },
+ res: {
+ babel7corejs3: true,
+ closure: false,
+ closure20200927: true,
+ ie11: false,
+ firefox10: false,
+ firefox52: false,
+ firefox73: false,
+ firefox74: true,
+ chrome77: false,
+ chrome80: false,
+ chrome89: false,
+ chrome90: false,
+ chrome91: true,
+ safari13_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm21_3_3: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'nullish coalescing operator (??)',
+ spec: 'https://github.com/tc39/proposal-nullish-coalescing',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Nullish_coalescing_operator',
+ category: '2020 features',
+ significance: 'small',
+ exec() {
+ /*
+ return (null ?? 42) === 42 &&
+ (undefined ?? 42) === 42 &&
+ (false ?? 42) === false &&
+ ('' ?? 42) === '' &&
+ (0 ?? 42) === 0 &&
+ isNaN(NaN ?? 42);
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20200315: true,
+ typescript3_7corejs3: true,
+ ie11: false,
+ firefox10: false,
+ firefox52: false,
+ firefox72: true,
+ chrome77: false,
+ chrome78: {
+ val: 'flagged',
+ note_id: 'chrome-nullish',
+ note_html: 'The feature has to be enabled via --js-flags="--harmony-nullish"
flag',
+ },
+ chrome80: true,
+ safari13_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: false,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'String.prototype.replaceAll',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-string-replace-all',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/replaceAll',
+ category: '2021 features',
+ exec() {
+ /*
+ return 'q=query+string+parameters'.replaceAll('+', ' ') === 'q=query string parameters';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ closure: false,
+ closure20210808: true,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox52: false,
+ firefox71: false,
+ firefox72: firefox.nightly,
+ firefox77: true,
+ chrome77: false,
+ chrome80: chrome.stringPrototypeReplaceAll,
+ chrome85: true,
+ safari13_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: false,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: graalvm.es2021flag,
+ graalvm21: true,
+ ios13_4: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Promise.any',
+ category: '2021 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-promise-any',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/any',
+ subtests: [
+ {
+ name: 'fulfillment',
+ exec() {
+ /*
+ Promise.any([
+ Promise.reject(1),
+ Promise.resolve(2),
+ Promise.resolve(3)
+ ]).then(it => {
+ if (it === 2) asyncTestPassed();
+ });
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ closure: false,
+ closure20210808: true,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox72: firefox.nightly,
+ firefox79: true,
+ chrome77: false,
+ chrome84: {
+ val: 'flagged',
+ note_id: 'chrome-promise-any',
+ note_html:
+ 'Available behind the --js-flags="--harmony-promise-any"
flag in V8.',
+ },
+ chrome85: true,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'AggregateError',
+ exec() {
+ /*
+ Promise.any([
+ Promise.reject(1),
+ Promise.reject(2),
+ Promise.reject(3)
+ ]).catch (error => {
+ if (error instanceof AggregateError && error.errors.length === 3) asyncTestPassed();
+ });
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ closure: false,
+ closure20210808: true,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox72: firefox.nightly,
+ firefox79: true,
+ chrome77: false,
+ chrome84: {
+ val: 'flagged',
+ note_id: 'chrome-promise-any',
+ note_html:
+ 'Available behind the --js-flags="--harmony-promise-any"
flag in V8.',
+ },
+ chrome85: true,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'WeakReferences',
+ spec: 'https://github.com/tc39/proposal-weakrefs',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakRef',
+ category: '2021 features',
+ significance: 'large',
+ subtests: [
+ {
+ name: 'WeakRef minimal support',
+ spec: 'https://github.com/tc39/proposal-weakrefs#weak-references',
+ exec() {
+ /*
+ var O = {};
+ var weakref = new WeakRef(O);
+ return weakref.deref() === O;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox2: false,
+ firefox74: {
+ val: 'flagged',
+ note_id: 'firefox-weakrefs',
+ note_html:
+ 'The feature has to be enabled via javascript.options.experimental.weakrefs
setting under about:config
.',
+ },
+ firefox79: true,
+ opera10_50: false,
+ chrome65: false,
+ chrome74: {
+ val: 'flagged',
+ note_id: 'chrome-weakrefs',
+ note_html:
+ 'Available behind the --js-flags="--harmony-weak-refs --expose-gc"
flag in V8.',
+ },
+ chrome85: true,
+ safari13: false,
+ safari14_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: false,
+ graalvm20: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'FinalizationRegistry minimal support',
+ spec: 'https://github.com/tc39/proposal-weakrefs#finalizers',
+ exec() {
+ /*
+ var fr = new FinalizationRegistry(function () {});
+ return Object.getPrototypeOf(fr) === FinalizationRegistry.prototype;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox2: false,
+ firefox74: false,
+ firefox78: { val: 'flagged', note_id: 'firefox-weakrefs' },
+ firefox79: true,
+ opera10_50: false,
+ chrome65: false,
+ chrome74: false,
+ chrome85: true,
+ safari14_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm19: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Logical Assignment',
+ category: '2021 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-logical-assignment/',
+ subtests: [
+ {
+ name: '||= basic support',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_OR_assignment',
+ exec() {
+ /*
+ let a;
+ let b = 0;
+ let c = 1;
+ a ||= 2;
+ b ||= 2;
+ c ||= 2;
+ return a === 2 && b === 2 && c === 1;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ ie11: false,
+ firefox60: false,
+ firefox76: false,
+ firefox77: firefox.nightly,
+ firefox79: true,
+ chrome80: false,
+ chrome84: {
+ val: 'flagged',
+ note_id: 'chrome-logical-assignment',
+ note_html:
+ 'Available behind the --js-flags="--logical-assignment"
flag in V8.',
+ },
+ chrome85: true,
+ safari13: false,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '||= short-circuiting behaviour',
+ exec() {
+ /*
+ let a = 1;
+ let i = 1;
+ a ||= ++i;
+ return a === 1 && i === 1;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ ie11: false,
+ firefox60: false,
+ firefox76: false,
+ firefox77: firefox.nightly,
+ firefox79: true,
+ chrome80: false,
+ chrome84: { val: 'flagged', note_id: 'chrome-logical-assignment' },
+ chrome85: true,
+ safari13: false,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '||= setter not unecessarily invoked',
+ exec() {
+ /*
+ let i = 1;
+ var obj = { get x() { return 1 }, set x(n) { i++; } };
+ obj.x ||= 2;
+ return i === 1;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ ie11: false,
+ firefox60: false,
+ firefox76: false,
+ firefox77: firefox.nightly,
+ firefox79: true,
+ chrome80: false,
+ chrome84: { val: 'flagged', note_id: 'chrome-logical-assignment' },
+ chrome85: true,
+ safari13: false,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '&&= basic support',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_AND_assignment',
+ exec() {
+ /*
+ let a;
+ let b = 0;
+ let c = 1;
+ a &&= 2;
+ b &&= 2;
+ c &&= 2;
+ return typeof a === 'undefined' && b === 0 && c === 2;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ ie11: false,
+ firefox60: false,
+ firefox76: false,
+ firefox77: firefox.nightly,
+ firefox79: true,
+ chrome80: false,
+ chrome84: { val: 'flagged', note_id: 'chrome-logical-assignment' },
+ chrome85: true,
+ safari13: false,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '&&= short-circuiting behaviour',
+ exec() {
+ /*
+ let a;
+ let i = 1;
+ a &&= ++i;
+ return typeof a === 'undefined' && i === 1;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ ie11: false,
+ firefox60: false,
+ firefox76: false,
+ firefox77: firefox.nightly,
+ firefox79: true,
+ chrome80: false,
+ chrome84: { val: 'flagged', note_id: 'chrome-logical-assignment' },
+ chrome85: true,
+ safari13: false,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '&&= setter not unecessarily invoked',
+ exec() {
+ /*
+ let i = 1;
+ var obj = { get x() { return }, set x(n) { i++; } };
+ obj.x &&= 2;
+ return i === 1;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ ie11: false,
+ firefox60: false,
+ firefox76: false,
+ firefox77: firefox.nightly,
+ firefox79: true,
+ chrome80: false,
+ chrome84: { val: 'flagged', note_id: 'chrome-logical-assignment' },
+ chrome85: true,
+ safari13: false,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '??= basic support',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Logical_nullish_assignment',
+ exec() {
+ /*
+ let a;
+ let b = 0;
+ let c = 1;
+ a ??= 2;
+ b ??= 2;
+ c ??= 2;
+ return a === 2 && b === 0 && c === 1;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ ie11: false,
+ firefox60: false,
+ firefox76: false,
+ firefox77: firefox.nightly,
+ firefox79: true,
+ chrome80: false,
+ chrome84: { val: 'flagged', note_id: 'chrome-logical-assignment' },
+ chrome85: true,
+ safari13: false,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '??= short-circuiting behaviour',
+ exec() {
+ /*
+ let a = 1;
+ let i = 1;
+ a ??= ++i;
+ return a === 1 && i === 1;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ ie11: false,
+ firefox60: false,
+ firefox76: false,
+ firefox77: firefox.nightly,
+ firefox79: true,
+ chrome80: false,
+ chrome84: { val: 'flagged', note_id: 'chrome-logical-assignment' },
+ chrome85: true,
+ safari13: false,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '??= setter not unecessarily invoked',
+ exec() {
+ /*
+ let i = 1;
+ var obj = { get x() { return 1 }, set x(n) { i++; } };
+ obj.x ??= 2;
+ return i === 1;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ ie11: false,
+ firefox60: false,
+ firefox76: false,
+ firefox77: firefox.nightly,
+ firefox79: true,
+ chrome80: false,
+ chrome84: { val: 'flagged', note_id: 'chrome-logical-assignment' },
+ chrome85: true,
+ safari13: false,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ graalvm20_3: graalvm.es2021flag,
+ graalvm21: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'numeric separators',
+ spec: 'https://github.com/tc39/proposal-numeric-separator',
+ category: '2021 features',
+ significance: 'small',
+ exec() {
+ /*
+ return 1_000_000.000_001 === 1000000.000001 &&
+ 0b1010_0001_1000_0101 === 0b1010000110000101;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20210808: true,
+ typescript1corejs2: false,
+ typescript2_7corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox10: false,
+ firefox67: false,
+ firefox68: firefox.nightly,
+ firefox70: true,
+ opera10_50: false,
+ chrome67: chrome.harmony,
+ chrome75: true,
+ safari13: true,
+ safaritp: true,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ jerryscript2_4_0: true,
+ graalvm19: false,
+ graalvm20: graalvm.es2020flag,
+ graalvm20_1: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'instance class fields',
+ category: '2022 features',
+ significance: 'medium',
+ spec: 'https://github.com/tc39/proposal-class-fields',
+ subtests: [
+ {
+ name: 'public instance class fields',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_elements#Public_instance_fields',
+ exec() {
+ /*
+ class C {
+ x = 'x';
+ }
+ return new C().x === 'x';
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ tr: true,
+ typescript1corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox67: firefox.classFields,
+ firefox69: true,
+ opera10_50: false,
+ chrome65: chrome.harmony,
+ chrome72: true,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm20: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'private instance class fields basic support',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_elements#Private_instance_fields',
+ exec() {
+ /*
+ class C {
+ #x;
+ constructor(x) {
+ this.#x = x;
+ }
+ x() {
+ return this.#x;
+ }
+ }
+ return new C(42).x() === 42;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox67: firefox.privateClassFields,
+ firefox80: firefox.privateFields,
+ firefox90: true,
+ opera10_50: false,
+ chrome66: chrome.harmony,
+ chrome74: true,
+ safari14_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm20: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'private instance class fields initializers',
+ exec() {
+ /*
+ class C {
+ #x = 42;
+ x() {
+ return this.#x;
+ }
+ }
+ return new C().x() === 42;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox67: firefox.privateClassFields,
+ firefox80: firefox.privateFields,
+ firefox90: true,
+ opera10_50: false,
+ chrome66: chrome.harmony,
+ chrome74: true,
+ safari14_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm20: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'optional private instance class fields access',
+ exec() {
+ /*
+ class C {
+ #x = 42;
+ x(o = this) {
+ return o?.#x;
+ }
+ }
+ return new C().x() === 42 && new C().x(null) === void undefined;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ babel7corejs3: true,
+ ie11: false,
+ firefox2: false,
+ firefox80: firefox.privateFields,
+ firefox90: true,
+ chrome1: false,
+ chrome83: false,
+ chrome84: true,
+ safari1: false,
+ safari13_1: false,
+ safari14_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ opera10_50: false,
+ graalvm20: false,
+ graalvm20_3: true,
+ typescript3_8corejs3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'optional deep private instance class fields access',
+ exec() {
+ /*
+ class C {
+ #x = 42;
+ x(o = { p: this }) {
+ return o?.p.#x;
+ }
+ }
+ return new C().x() === 42 && new C().x(null) === void undefined;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ babel7corejs3: true,
+ ie11: false,
+ firefox2: false,
+ firefox74: firefox.privateClassFields,
+ firefox80: firefox.privateFields,
+ firefox90: true,
+ chrome1: false,
+ chrome78: {
+ val: 'flagged',
+ note_id: 'chrome-optional-chaining',
+ note_html: 'The feature has to be enabled via --js-flags="--harmony-optional-chaining"
flag',
+ },
+ chrome80: true,
+ safari1: false,
+ safari13_1: false,
+ safari14_1: true,
+ safaritp: true,
+ opera10_50: false,
+ duktape2_0: false,
+ graalvm20: false,
+ graalvm20_3: true,
+ typescript3_8corejs3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed instance class fields',
+ exec() {
+ /*
+ class C {
+ ['x'] = 42;
+ }
+ return new C().x === 42;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox66: false,
+ firefox68: firefox.classFields,
+ firefox69: true,
+ opera10_50: false,
+ chrome73: true,
+ safari14: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm20: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'resolving identifier in parent scope',
+ exec() {
+ /*
+ {
+ let a = ["hello world"];
+ class MyClass {
+ // The parenthesis below are required to trigger https://bugs.webkit.org/show_bug.cgi?id=236843
+ c = a[(0)];
+ }
+ return new MyClass().c === a[0];
+ }
+ */
+ },
+ res: {
+ firefox122: true,
+ chrome74: true,
+ chrome124: true,
+ firefox69: true,
+ safari15: false,
+ safari16: true,
+ safari17: true,
+ safaritp: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'static class fields',
+ category: '2022 features',
+ significance: 'medium',
+ spec: 'https://github.com/tc39/proposal-static-class-features/',
+ subtests: [
+ {
+ name: 'public static class fields',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_elements#Public_static_fields',
+ exec() {
+ /*
+ class C {
+ static x = 'x';
+ }
+ return C.x === 'x';
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ tr: true,
+ typescript1corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox74: false,
+ firefox75: true,
+ opera10_50: false,
+ chrome71: chrome.harmony,
+ chrome72: true,
+ safari14_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm20: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'static class fields use [[Define]]',
+ exec() {
+ /*
+ return (class X { static name = "name"; }).name === 'name';
+ */
+ },
+ res: {
+ ie11: false,
+ edge18: false,
+ chrome73: true,
+ chrome90: true,
+ chrome94: true,
+ chrome96: true,
+ chrome97: false,
+ chrome98: true,
+ firefox74: false,
+ firefox75: true,
+ firefox91: true,
+ firefox95: true,
+ firefox96: true,
+ opera10_50: false,
+ node11_0: false,
+ node12_0: true,
+ node12_5: true,
+ node12_9: true,
+ node12_11: true,
+ node13_0: true,
+ node13_2: true,
+ node14_0: true,
+ node14_5: true,
+ node14_6: true,
+ node15_0: true,
+ node16_0: true,
+ node16_9: true,
+ node16_11: true,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_15: false,
+ },
+ },
+ {
+ name: 'private static class fields',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Class_elements#Private_static_fields',
+ exec() {
+ /*
+ class C {
+ static #x = 42;
+ x() {
+ return C.#x;
+ }
+ }
+ return new C().x() === 42;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox80: firefox.privateFields,
+ firefox90: true,
+ opera10_50: false,
+ chrome74: true,
+ safari14_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm20: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed static class fields',
+ exec() {
+ /*
+ class C {
+ static ['x'] = 42;
+ }
+ return C.x === 42;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ ie11: false,
+ firefox2: false,
+ firefox74: false,
+ firefox75: true,
+ opera10_50: false,
+ chrome73: true,
+ safari14_1: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm20: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'private class methods',
+ category: '2022 features',
+ significance: 'medium',
+ spec: 'https://github.com/tc39/proposal-private-methods',
+ subtests: [
+ {
+ name: 'private instance methods',
+ exec() {
+ /*
+ class C {
+ #x() { return 42; }
+ x() {
+ return this.#x();
+ }
+ }
+ return new C().x() === 42;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ ie11: false,
+ firefox60: false,
+ firefox68: false,
+ firefox75: false,
+ firefox81: {
+ val: 'flagged',
+ note_id: 'ff-private-instance-methods-and-accessors',
+ note_html:
+ 'The feature has to be enabled via javascript.options.experimental.private_fields
and javascript.options.experimental.private_methods
settings under about:config
.',
+ },
+ firefox90: true,
+ opera10_50: false,
+ chrome79: chrome.harmony,
+ chrome84: true,
+ duktape2_0: false,
+ safari13: false,
+ safari15: true,
+ safaritp: true,
+ graalvm20: false,
+ graalvm20_1: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'private static methods',
+ exec() {
+ /*
+ class C {
+ static #x() { return 42; }
+ x() {
+ return C.#x();
+ }
+ }
+ return new C().x() === 42;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ ie11: false,
+ firefox60: false,
+ firefox68: false,
+ firefox75: false,
+ firefox82: {
+ val: 'flagged',
+ note_id: 'ff-private-instance-methods-and-accessors',
+ },
+ firefox90: true,
+ opera10_50: false,
+ chrome79: chrome.harmony,
+ chrome84: true,
+ duktape2_0: false,
+ safari13: false,
+ safari15: true,
+ safaritp: true,
+ graalvm20: false,
+ graalvm20_1: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'private accessor properties',
+ exec() {
+ /*
+ var y = false;
+ class C {
+ get #x() { return 42; }
+ set #x(x) { y = x; }
+ x() {
+ this.#x = true;
+ return this.#x;
+ }
+ }
+ return new C().x() === 42 && y;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ ie11: false,
+ firefox60: false,
+ firefox68: false,
+ firefox75: false,
+ firefox81: {
+ val: 'flagged',
+ note_id: 'ff-private-instance-methods-and-accessors',
+ },
+ firefox90: true,
+ opera10_50: false,
+ chrome79: chrome.harmony,
+ chrome84: true,
+ duktape2_0: false,
+ safari13: false,
+ safari15: true,
+ safaritp: true,
+ graalvm20: false,
+ graalvm20_1: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'private static accessor properties',
+ exec() {
+ /*
+ var y = false;
+ class C {
+ static get #x() { return 42; }
+ static set #x(x) { y = x; }
+ x() {
+ C.#x = true;
+ return C.#x;
+ }
+ }
+ return new C().x() === 42 && y;
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ ie11: false,
+ firefox60: false,
+ firefox68: false,
+ firefox75: false,
+ firefox82: {
+ val: 'flagged',
+ note_id: 'ff-private-instance-methods-and-accessors',
+ },
+ firefox90: true,
+ opera10_50: false,
+ chrome79: chrome.harmony,
+ chrome84: true,
+ duktape2_0: false,
+ safari13: false,
+ safari15: true,
+ safaritp: true,
+ graalvm20: false,
+ graalvm20_1: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Ergonomic brand checks for private fields',
+ category: '2022 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-private-fields-in-in',
+ exec() {
+ /*
+ class A {
+ #x;
+ static check(obj) {
+ return #x in obj;
+ }
+ }
+ return A.check(new A) && !A.check({});
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs2: true,
+ babel7corejs3: true,
+ chrome1: false,
+ chrome91: true,
+ edge18: false,
+ firefox2: false,
+ firefox90: true,
+ ie11: false,
+ opera10_50: false,
+ safari12: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: graalvm.esStagingFlag,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.at() method on the built-in indexables',
+ category: '2022 features',
+ significance: 'tiny',
+ spec: 'https://github.com/tc39/proposal-relative-indexing-method/',
+ subtests: [
+ {
+ name: 'Array.prototype.at()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/at',
+ exec() {
+ /*
+ var arr = [1, 2, 3];
+ return arr.at(0) === 1
+ && arr.at(-3) === 1
+ && arr.at(1) === 2
+ && arr.at(-2) === 2
+ && arr.at(2) === 3
+ && arr.at(-1) === 3
+ && arr.at(3) === undefined
+ && arr.at(-4) === undefined;
+ */
+ },
+ res: {
+ closure: false,
+ closure20220502: {
+ val: false,
+ note_id: 'closure-at-method',
+ note_html: 'Requires native support for Math.trunc
',
+ },
+ closure20220719: true,
+ ie11: false,
+ firefox68: false,
+ firefox85: firefox.nightly,
+ firefox90: true,
+ chrome85: false,
+ chrome92: true,
+ safari14_1: {
+ val: 'flagged',
+ note_id: 'safari-at-method',
+ note_html: 'The feature has to be enabled via jscOptions=--useAtMethod=true
flag.',
+ },
+ safari15_4: true,
+ safaritp: true,
+ duktape2_0: false,
+ babel7corejs3: babel.corejs,
+ typescript4corejs3: typescript.corejs,
+ graalvm21: graalvm.es2022flag,
+ graalvm21_3_3: graalvm.esStagingFlag,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'String.prototype.at()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/at',
+ exec() {
+ /*
+ var str = 'abc';
+ return str.at(0) === 'a'
+ && str.at(-3) === 'a'
+ && str.at(1) === 'b'
+ && str.at(-2) === 'b'
+ && str.at(2) === 'c'
+ && str.at(-1) === 'c'
+ && str.at(3) === undefined
+ && str.at(-4) === undefined;
+ */
+ },
+ res: {
+ closure: false,
+ closure20220502: {
+ val: false,
+ note_id: 'closure-at-method',
+ },
+ closure20220719: true,
+ ie11: false,
+ firefox68: false,
+ firefox85: firefox.nightly,
+ firefox90: true,
+ chrome85: false,
+ chrome92: true,
+ safari14_1: {
+ val: 'flagged',
+ note_id: 'safari-at-method',
+ },
+ safari15_4: true,
+ safaritp: true,
+ duktape2_0: false,
+ babel7corejs3: babel.corejs,
+ typescript4corejs3: typescript.corejs,
+ graalvm21: graalvm.es2022flag,
+ graalvm21_3_3: graalvm.esStagingFlag,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: '%TypedArray%.prototype.at()',
+ exec() {
+ /*
+ return [
+ 'Int8Array',
+ 'Uint8Array',
+ 'Uint8ClampedArray',
+ 'Int16Array',
+ 'Uint16Array',
+ 'Int32Array',
+ 'Uint32Array',
+ 'Float32Array',
+ 'Float64Array'
+ ].every(function (TypedArray) {
+ var Constructor = globalThis[TypedArray];
+ if (typeof Constructor !== 'function') {
+ return false;
+ }
+ var arr = new Constructor([1, 2, 3]);
+ return arr.at(0) === 1
+ && arr.at(-3) === 1
+ && arr.at(1) === 2
+ && arr.at(-2) === 2
+ && arr.at(2) === 3
+ && arr.at(-1) === 3
+ && arr.at(3) === undefined
+ && arr.at(-4) === undefined;
+ });
+ */
+ },
+ res: {
+ closure: false,
+ closure20220502: {
+ val: false,
+ note_id: 'closure-typed-array',
+ note_html: 'Requires native support for typed arrays',
+ },
+ ie11: false,
+ firefox68: false,
+ firefox85: firefox.nightly,
+ firefox90: true,
+ chrome85: false,
+ chrome92: true,
+ safari14_1: {
+ val: 'flagged',
+ note_id: 'safari-at-method',
+ },
+ safari15_4: true,
+ safaritp: true,
+ duktape2_0: false,
+ babel7corejs3: babel.corejs,
+ typescript4corejs3: typescript.corejs,
+ graalvm21: graalvm.es2022flag,
+ graalvm21_3_3: graalvm.esStagingFlag,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Object.hasOwn',
+ category: '2022 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-accessible-object-hasownproperty',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/hasOwn',
+ subtests: [
+ {
+ name: 'Basic functionality',
+ exec() {
+ /*
+ return Object.hasOwn({ x: 2 }, "x") === true;
+ */
+ },
+ res: {
+ babel7corejs3: babel.corejs,
+ closure20220719: true,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ chrome1: false,
+ chrome90: false,
+ chrome93: true,
+ edge18: false,
+ firefox2: false,
+ firefox90: false,
+ firefox91: firefox.nightly,
+ firefox92: true,
+ opera10_50: false,
+ safari12: false,
+ safari15_4: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm21_3_3: graalvm.esStagingFlag,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'ToObject called before ToPropertyKey',
+ exec() {
+ /*
+ var ok = !!Object.hasOwn;
+ try {
+ Object.hasOwn(null, { toString: function () { ok = false } });
+ return false;
+ } catch (e) {
+ return ok;
+ }
+ */
+ },
+ res: {
+ babel7corejs3: babel.corejs,
+ closure20220719: true,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ chrome1: false,
+ chrome90: false,
+ chrome93: true,
+ edge18: false,
+ firefox2: false,
+ firefox90: false,
+ firefox91: firefox.nightly,
+ firefox92: true,
+ opera10_50: false,
+ safari12: false,
+ safari15_4: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm21_3_3: graalvm.esStagingFlag,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Class static initialization blocks',
+ category: '2022 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-class-static-block',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes/Static_initialization_blocks',
+ exec() {
+ /*
+ let ok = false;
+ class A {
+ static { ok = true; }
+ }
+ return ok;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs2: true,
+ babel7corejs3: true,
+ chrome1: false,
+ chrome91: {
+ val: 'flagged',
+ note_id: 'ch-static-init-blocks',
+ note_html: 'The feature has to be enabled via harmony_class_static_blocks
flag.',
+ },
+ chrome94: true,
+ safari13: false,
+ edge18: false,
+ firefox2: false,
+ firefox87: false,
+ firefox90: {
+ val: 'flagged',
+ note_id: 'ff-static-init-blocks',
+ note_html:
+ 'The feature has to be enabled via javascript.options.experimental.class_static_blocks=true
flag.',
+ },
+ firefox93: true,
+ ie11: false,
+ opera10_50: false,
+ safari16_4: true,
+ duktape2_0: false,
+ graalvm21_3_3: graalvm.esStagingFlag,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Error.cause property',
+ category: '2022 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-error-cause',
+ subtests: [
+ {
+ name: 'Error has cause',
+ exec() {
+ /*
+ var error = new Error('error', { cause: 'cause' })
+ return error.hasOwnProperty('cause') && error.cause === 'cause';
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: false,
+ },
+ },
+ {
+ name: 'Error.prototype lacks cause',
+ exec() {
+ /*
+ return !('cause' in Error.prototype);
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: false,
+ chrome94: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'EvalError has cause',
+ exec() {
+ /*
+ var error = new EvalError('error', { cause: 'cause' })
+ return error.hasOwnProperty('cause') && error.cause === 'cause';
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: false,
+ },
+ },
+ {
+ name: 'EvalError.prototype lacks cause',
+ exec() {
+ /*
+ return !('cause' in EvalError.prototype);
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: false,
+ chrome94: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'RangeError has cause',
+ exec() {
+ /*
+ var error = new RangeError('error', { cause: 'cause' })
+ return error.hasOwnProperty('cause') && error.cause === 'cause';
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: false,
+ },
+ },
+ {
+ name: 'RangeError.prototype lacks cause',
+ exec() {
+ /*
+ return !('cause' in RangeError.prototype);
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: false,
+ chrome94: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'ReferenceError has cause',
+ exec() {
+ /*
+ var error = new ReferenceError('error', { cause: 'cause' })
+ return error.hasOwnProperty('cause') && error.cause === 'cause';
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: false,
+ },
+ },
+ {
+ name: 'ReferenceError.prototype lacks cause',
+ exec() {
+ /*
+ return !('cause' in ReferenceError.prototype);
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: false,
+ chrome94: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'SyntaxError has cause',
+ exec() {
+ /*
+ var error = new SyntaxError('error', { cause: 'cause' })
+ return error.hasOwnProperty('cause') && error.cause === 'cause';
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: false,
+ },
+ },
+ {
+ name: 'SyntaxError.prototype lacks cause',
+ exec() {
+ /*
+ return !('cause' in SyntaxError.prototype);
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: false,
+ chrome94: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'TypeError has cause',
+ exec() {
+ /*
+ var error = new TypeError('error', { cause: 'cause' })
+ return error.hasOwnProperty('cause') && error.cause === 'cause';
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: false,
+ },
+ },
+ {
+ name: 'TypeError.prototype lacks cause',
+ exec() {
+ /*
+ return !('cause' in TypeError.prototype);
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: false,
+ chrome94: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'URIError has cause',
+ exec() {
+ /*
+ var error = new URIError('error', { cause: 'cause' })
+ return error.hasOwnProperty('cause') && error.cause === 'cause';
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: false,
+ },
+ },
+ {
+ name: 'URIError.prototype lacks cause',
+ exec() {
+ /*
+ return !('cause' in URIError.prototype);
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: false,
+ chrome94: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'AggregateError has cause',
+ exec() {
+ /*
+ var error = new AggregateError([], 'error', { cause: 'cause' })
+ return error.hasOwnProperty('cause') && error.cause === 'cause';
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_14: false,
+ },
+ },
+ {
+ name: 'AggregateError.prototype lacks cause',
+ exec() {
+ /*
+ return !('cause' in AggregateError.prototype);
+ */
+ },
+ res: {
+ ie11: false,
+ chrome1: false,
+ chrome92: false,
+ chrome93: false,
+ chrome94: true,
+ edge90: false,
+ firefox45: false,
+ firefox90: false,
+ firefox91: true,
+ safari14: false,
+ safari15: true,
+ duktape2_0: false,
+ graalvm21_3_3: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_14: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'RegExp Match Indices (`hasIndices` / `d` flag)',
+ category: '2022 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-regexp-match-indices',
+ subtests: [
+ {
+ name: 'constructor supports it',
+ exec() {
+ /*
+ return new RegExp('a', 'd') instanceof RegExp;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox68: false,
+ firefox78: false,
+ firefox91: true,
+ safari15: true,
+ chrome90: true,
+ graalvm21_3_3: graalvm.esStagingFlag,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_15: false,
+ },
+ },
+ {
+ name: 'shows up in flags',
+ exec() {
+ /*
+ var expected = ['hasIndices'];
+ // Sorted alphabetically by shortname – "dgimsuy".
+ if ('global' in RegExp.prototype) expected.push('global');
+ if ('ignoreCase' in RegExp.prototype) expected.push('ignoreCase');
+ if ('multiline' in RegExp.prototype) expected.push('multiline');
+ if ('dotAll' in RegExp.prototype) expected.push('dotAll');
+ if ('unicode' in RegExp.prototype) expected.push('unicode');
+ if ('sticky' in RegExp.prototype) expected.push('sticky');
+ var actual = [];
+ var p = new Proxy({}, { get: function (o, k) { actual.push(k); return o[k]; }});
+ Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.call(p);
+ if (expected.length !== actual.length) return false;
+ for (var i = 0; i < expected.length; i++) {
+ if (expected[i] !== actual[i]) return false;
+ }
+ return true;
+ */
+ },
+ res: {
+ ie11: false,
+ node16_0: false,
+ firefox68: false,
+ firefox78: false,
+ firefox91: true,
+ firefox116: false,
+ safari15: true,
+ chrome90: false,
+ graalvm21_3_3: graalvm.esStagingFlag,
+ graalvm22_2: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_15: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Array find from last',
+ category: '2023 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-array-find-from-last',
+ subtests: [
+ {
+ name: 'Array.prototype.findLast',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLast',
+ exec() {
+ /*
+ var arr = [{ x: 1 }, { x: 2 }, { x: 1 }, { x: 2 }];
+ return arr.findLast(function (o) { return o.x === 1; }) === arr[2];
+ */
+ },
+ res: {
+ babel7corejs3: babel.corejs,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ chrome1: false,
+ chrome90: false,
+ chrome96: false,
+ chrome97: true,
+ edge18: false,
+ firefox2: false,
+ firefox89: false,
+ firefox102: false,
+ firefox103: {
+ val: 'flagged',
+ note_id: 'firefox-arrayfindfromlast',
+ note_html:
+ 'The feature has to be enabled via javascript.options.experimental.array_find_last
setting under about:config
.',
+ },
+ firefox104: true,
+ opera10_50: false,
+ safari12: false,
+ safari15_4: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: graalvm.esStagingFlag,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.findLastIndex',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findLastIndex',
+ exec() {
+ /*
+ var arr = [{ x: 1 }, { x: 2 }, { x: 1 }, { x: 2 }];
+ return arr.findLastIndex(function (o) { return o.x === 1; }) === 2;
+ */
+ },
+ res: {
+ babel7corejs3: babel.corejs,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ chrome1: false,
+ chrome90: false,
+ chrome96: false,
+ chrome97: true,
+ edge18: false,
+ firefox2: false,
+ firefox89: false,
+ firefox102: false,
+ firefox103: { val: 'flagged', note_id: 'firefox-arrayfindfromlast' },
+ firefox104: true,
+ opera10_50: false,
+ safari12: false,
+ safari15_4: true,
+ safaritp: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ graalvm22_2: graalvm.esStagingFlag,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Hashbang Grammar',
+ category: '2023 features',
+ significance: 'tiny',
+ spec: 'https://github.com/tc39/proposal-hashbang/',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#Hashbang_comments',
+ exec() {
+ /*
+ try {
+ return !eval('#!/wash/your/hands');
+ } catch (e) {
+ return false
+ }
+ */
+ },
+ res: {
+ chrome1: false,
+ chrome74: true,
+ firefox2: false,
+ firefox67: true,
+ ie11: false,
+ opera10_50: false,
+ edge18: false,
+ safari1: false,
+ safari13: false,
+ safari13_1: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm20_1: true,
+ babel7corejs3: false,
+ typescript3_2corejs3: false,
+ closure: false,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Change Array by copy',
+ category: '2023 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-change-array-by-copy',
+ subtests: [
+ {
+ name: 'Array.prototype.toReversed()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toReversed',
+ exec() {
+ /*
+ var arr = [1, 2, 3];
+ return arr.toReversed()[0] === 3 && arr[0] === 1;
+ */
+ },
+ res: {
+ babel7corejs3: babel.corejs,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ chrome94: false,
+ chrome109: false,
+ chrome110: true,
+ firefox45: false,
+ firefox95: {
+ val: 'flagged',
+ note_id: 'fx-change-array-by-copy',
+ note_html: 'The feature has to be enabled via --enable-change-array-by-copy flag',
+ },
+ firefox115: true,
+ safari15_5: false,
+ safari16: true,
+ },
+ },
+ {
+ name: 'Array.prototype.toSorted()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSorted',
+ exec() {
+ /*
+ var arr = ['C', 'A', 'B'];
+ return arr.toSorted()[0] === 'A' && arr[0] === 'C';
+ */
+ },
+ res: {
+ babel7corejs3: babel.corejs,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ chrome94: false,
+ chrome109: false,
+ chrome110: true,
+ firefox45: false,
+ firefox95: { val: 'flagged', note_id: 'fx-change-array-by-copy' },
+ firefox115: true,
+ safari15_5: false,
+ safari16: true,
+ },
+ },
+ {
+ name: 'Array.prototype.toSpliced()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/toSpliced',
+ exec() {
+ /*
+ var arr = ['A', 'C'];
+ return arr.toSpliced(1, 0, 'B')[1] === 'B' && arr[1] === 'C';
+ */
+ },
+ res: {
+ babel7corejs3: babel.corejs,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ chrome94: false,
+ chrome109: false,
+ chrome110: true,
+ firefox45: false,
+ firefox95: { val: 'flagged', note_id: 'fx-change-array-by-copy' },
+ firefox115: true,
+ safari15_5: false,
+ safari16: true,
+ },
+ },
+ {
+ name: 'Array.prototype.with()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/with',
+ exec() {
+ /*
+ var arr = ['A', 'X', 'C'];
+ return arr.with(1, 'B')[1] === 'B' && arr[1] === 'X';
+ */
+ },
+ res: {
+ babel7corejs3: babel.corejs,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ chrome94: false,
+ chrome109: false,
+ chrome110: true,
+ firefox45: false,
+ firefox95: { val: 'flagged', note_id: 'fx-change-array-by-copy' },
+ firefox115: true,
+ safari15_5: false,
+ safari16: true,
+ },
+ },
+ {
+ name: 'TypedArray.prototype.toReversed()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/toReversed',
+ exec() {
+ /*
+ var arr = new Uint8Array([1, 2, 3]);
+ return arr.toReversed()[0] == 3 && arr[0] == 1;
+ */
+ },
+ res: {
+ ie11: false,
+ chrome94: false,
+ chrome109: false,
+ chrome110: true,
+ firefox45: false,
+ firefox95: { val: 'flagged', note_id: 'fx-change-array-by-copy' },
+ firefox115: true,
+ safari15_5: false,
+ safari16: true,
+ },
+ },
+ {
+ name: 'TypedArray.prototype.toSorted()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/toSorted',
+ exec() {
+ /*
+ var arr = new Uint8Array([3, 1, 2]);
+ return arr.toSorted()[0] == 1 && arr[0] == 3;
+ */
+ },
+ res: {
+ ie11: false,
+ chrome94: false,
+ chrome109: false,
+ chrome110: true,
+ firefox45: false,
+ firefox95: { val: 'flagged', note_id: 'fx-change-array-by-copy' },
+ firefox115: true,
+ safari15_5: false,
+ safari16: true,
+ },
+ },
+ {
+ name: 'TypedArray.prototype.with()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/with',
+ exec() {
+ /*
+ var arr = new Uint8Array([1, 0, 2]);
+ return arr.with(1, 2)[1] == 2 && arr[1] == 0;
+ */
+ },
+ res: {
+ ie11: false,
+ chrome94: false,
+ chrome109: false,
+ chrome110: true,
+ firefox45: false,
+ firefox95: { val: 'flagged', note_id: 'fx-change-array-by-copy' },
+ firefox115: true,
+ safari15_5: false,
+ safari16: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'RegExp `v` flag',
+ category: '2024 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-regexp-v-flag',
+ subtests: [
+ {
+ name: 'set notations',
+ exec() {
+ /*
+ return /[\p{ASCII}&&\p{Decimal_Number}]/v.test("0")
+ && /[\p{Any}--[\x01-\u{10ffff}]]/v.test("\0")
+ */
+ },
+ res: {
+ chrome110: false,
+ chrome111: chrome.harmony,
+ chrome112: true,
+ firefox91: false,
+ firefox102: false,
+ firefox115: false,
+ firefox116: true,
+ ie11: false,
+ safari16_6: false,
+ safari17: true,
+ safaritp: true,
+ rhino1_7_15: false,
+ },
+ },
+ {
+ name: 'properties of Strings',
+ exec() {
+ /*
+ return /^\p{Emoji_Keycap_Sequence}$/v.test("*\uFE0F\u20E3")
+ && !/^\p{Emoji_Keycap_Sequence}$/v.test("*");
+ */
+ },
+ res: {
+ chrome110: false,
+ chrome111: chrome.harmony,
+ chrome112: true,
+ firefox91: false,
+ firefox102: false,
+ firefox115: false,
+ firefox116: true,
+ ie11: false,
+ safari16_6: false,
+ safari17: true,
+ safaritp: true,
+ rhino1_7_15: false,
+ },
+ },
+ {
+ name: 'constructor supports it',
+ exec() {
+ /*
+ return new RegExp('a', 'v') instanceof RegExp;
+ */
+ },
+ res: {
+ chrome110: false,
+ chrome111: chrome.harmony,
+ chrome112: true,
+ firefox91: false,
+ firefox102: false,
+ firefox115: false,
+ firefox116: true,
+ ie11: false,
+ safari16_6: false,
+ safari17: true,
+ safaritp: true,
+ rhino1_7_15: false,
+ },
+ },
+ {
+ name: 'shows up in flags',
+ exec() {
+ /*
+ var flags = [];
+ var p = new Proxy({}, { get: function (o, k) { flags.push(k); return o[k]; }});
+ Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.call(p);
+ return flags.indexOf("unicodeSets") !== -1;
+ */
+ },
+ res: {
+ chrome110: false,
+ chrome111: chrome.harmony,
+ chrome112: true,
+ firefox91: false,
+ firefox102: false,
+ firefox115: false,
+ firefox116: true,
+ ie11: false,
+ safari16_6: false,
+ safari17: true,
+ safaritp: true,
+ rhino1_7_15: false,
+ },
+ },
+ {
+ name: 'Unicode 15.1',
+ exec() {
+ /*
+ return /^\p{RGI_Emoji}$/v.test("🐦🔥");
+ */
+ },
+ res: {
+ chrome117: false,
+ chrome118: false,
+ chrome124: false,
+ chrome125: true,
+ chrome126: true,
+ node20_0: false,
+ node21_0: false,
+ node22_0: true,
+ firefox115: false,
+ firefox117: false,
+ firefox118: false,
+ firefox133: false,
+ firefox134: true,
+ safaritp: false,
+ safari16_6: false,
+ safari18: true,
+ ie11: false,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ hermes0_7_0: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Unicode 16.0',
+ exec() {
+ /*
+ return /^\p{RGI_Emoji}$/v.test("🇨🇶");
+ */
+ },
+ res: {
+ ie11: false,
+ chrome128: false,
+ node22_0: false,
+ firefox115: false,
+ firefox130: false,
+ firefox133: false,
+ firefox134: true,
+ safari17_6: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'ArrayBuffer.prototype.transfer',
+ category: '2024 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-arraybuffer-transfer',
+ subtests: [
+ {
+ name: 'ArrayBuffer.prototype.transfer()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/transfer',
+ exec() {
+ /*
+ const buffer1 = new Uint8Array([1, 2]).buffer;
+ const buffer2 = buffer1.transfer();
+ return buffer1.byteLength === 0
+ && buffer2.byteLength === 2;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox10: false,
+ firefox52: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'firefox-arraybuffer',
+ note_html:
+ 'The feature has to be enabled via javascript.options.experimental.arraybuffer_transfer
setting under about:config
.',
+ },
+ firefox122: true,
+ chrome70: false,
+ chrome114: true,
+ safari12: false,
+ safari17_4: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'ArrayBuffer.prototype.transferToFixedLength()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/transferToFixedLength',
+ exec() {
+ /*
+ const buffer1 = new Uint8Array([1, 2]).buffer;
+ const buffer2 = buffer1.transferToFixedLength();
+ return buffer1.byteLength === 0
+ && buffer2.byteLength === 2;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox115: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'firefox-arraybuffer',
+ },
+ firefox122: true,
+ chrome114: true,
+ safari17_4: true,
+ },
+ },
+ {
+ name: 'ArrayBuffer.prototype.detached',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/detached',
+ exec() {
+ /*
+ const buffer1 = new Uint8Array([1, 2]).buffer;
+ const buffer2 = buffer1.transfer();
+ return buffer1.detached && !buffer2.detached;
+ */
+ },
+ res: {
+ ie11: false,
+ firefox115: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'firefox-arraybuffer',
+ },
+ firefox122: true,
+ chrome114: true,
+ safari17_4: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Promise.withResolvers',
+ category: '2024 features',
+ significance: 'tiny',
+ spec: 'https://tc39.es/proposal-promise-with-resolvers/',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/withResolvers',
+ exec() {
+ /*
+ var obj = Promise.withResolvers();
+ return obj instanceof Object
+ && obj.promise instanceof Promise
+ && typeof obj.resolve === 'function'
+ && typeof obj.reject === 'function';
+ */
+ },
+ res: {
+ ie11: false,
+ chrome119: true,
+ firefox115: false,
+ firefox121: true,
+ node22_0: true,
+ safari17_6: true,
+ safaritp: true,
+ },
+ },
+ {
+ name: 'Array Grouping',
+ category: '2024 features',
+ significance: 'small',
+ spec: 'https://github.com/tc39/proposal-array-grouping',
+ subtests: [
+ {
+ name: 'Object.groupBy()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/groupBy',
+ exec() {
+ /*
+ const array = [1, 2, 3, 4];
+ const obj = Object.groupBy(array, (num, index) => {
+ return num % 2 === 0 ? 'even': 'odd';
+ });
+ return !('toString' in obj) && obj.even[0] == 2 && obj.odd[0] == 1;
+ */
+ },
+ res: {
+ ie11: false,
+ chrome117: true,
+ firefox97: false,
+ firefox98: {
+ val: 'flagged',
+ note_id: 'ff-array-grouping',
+ note_html:
+ 'The feature is only available on Nightly builds, and has to be enabled via javascript.options.experimental.array_grouping
setting under about:config
.',
+ },
+ firefox119: true,
+ safari17_4: true,
+ },
+ },
+ {
+ name: 'Map.groupBy()',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/groupBy',
+ exec() {
+ /*
+ const array = [1, 2, 3, 4];
+ const odd = { odd: true };
+ const even = { even: true };
+ const map = Map.groupBy(array, (num, index) => {
+ return num % 2 === 0 ? even: odd;
+ });
+ return map instanceof Map && map.get(even)[0] === 2 && map.get(odd)[0] === 1;
+ */
+ },
+ res: {
+ ie11: false,
+ chrome117: true,
+ firefox97: false,
+ firefox98: {
+ val: 'flagged',
+ note_id: 'ff-array-grouping',
+ },
+ firefox119: true,
+ safari17_4: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Duplicate named capturing groups',
+ category: '2025 features',
+ significance: 'tiny',
+ spec: 'https://github.com/tc39/proposal-duplicate-named-capturing-groups',
+ exec() {
+ /*
+ return /(?[0-9]{4})-[0-9]{2}|[0-9]{2}-(?[0-9]{4})/.test("12-1995");
+ */
+ },
+ res: {
+ chrome123: false,
+ chrome126: true,
+ deno1_42: false,
+ node21_0: false,
+ firefox115: false,
+ firefox128: false,
+ firefox129: true,
+ safari17_4: true,
+ safaritp: true,
+ ie11: false,
+ duktape2_0: false,
+ jerryscript2_3_0: false,
+ hermes0_7_0: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Set methods',
+ category: '2025 features',
+ significance: 'medium',
+ spec: 'https://github.com/tc39/proposal-set-methods',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set#instance_methods',
+ subtests: [
+ {
+ name: 'Set.prototype.intersection()',
+ exec() {
+ /*
+ var set = new Set([1, 2, 3]).intersection(new Set([2, 3, 4]));
+ return set.size === 2
+ && set.has(2)
+ && set.has(3);
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox117: false,
+ firefox118: {
+ val: 'flagged',
+ note_id: 'ff-new-set-methods',
+ note_html:
+ 'The feature has to be enabled via javascript.options.experimental.new_set_methods
setting under about:config
.',
+ },
+ firefox127: true,
+ chrome77: false,
+ chrome122: true,
+ safari17: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm21_3_3: graalvm.newSetMethodsFlag,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Set.prototype.union()',
+ exec() {
+ /*
+ var set = new Set([1, 2]).union(new Set([2, 3]));
+ return set.size === 3
+ && set.has(1)
+ && set.has(2)
+ && set.has(3);
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox117: false,
+ firefox118: {
+ val: 'flagged',
+ note_id: 'ff-new-set-methods',
+ },
+ firefox127: true,
+ chrome77: false,
+ chrome122: true,
+ safari17: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm21_3_3: graalvm.newSetMethodsFlag,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Set.prototype.difference()',
+ exec() {
+ /*
+ var set = new Set([1, 2, 3]).difference(new Set([3, 4]));
+ return set.size === 2
+ && set.has(1)
+ && set.has(2);
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox117: false,
+ firefox118: {
+ val: 'flagged',
+ note_id: 'ff-new-set-methods',
+ },
+ firefox127: true,
+ chrome77: false,
+ chrome122: true,
+ safari17: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm21_3_3: graalvm.newSetMethodsFlag,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Set.prototype.symmetricDifference()',
+ exec() {
+ /*
+ var set = new Set([1, 2]).symmetricDifference(new Set([2, 3]));
+ return set.size === 2
+ && set.has(1)
+ && set.has(3);
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox117: false,
+ firefox118: {
+ val: 'flagged',
+ note_id: 'ff-new-set-methods',
+ },
+ firefox127: true,
+ chrome77: false,
+ chrome122: true,
+ safari17: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm21_3_3: graalvm.newSetMethodsFlag,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Set.prototype.isDisjointFrom()',
+ exec() {
+ /*
+ return new Set([1, 2, 3]).isDisjointFrom(new Set([4, 5, 6]));
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox117: false,
+ firefox118: {
+ val: 'flagged',
+ note_id: 'ff-new-set-methods',
+ },
+ firefox127: true,
+ chrome77: false,
+ chrome122: true,
+ safari17: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm20_1: graalvm.es2021flag,
+ graalvm21_3_3: graalvm.newSetMethodsFlag,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Set.prototype.isSubsetOf()',
+ exec() {
+ /*
+ return new Set([1, 2, 3]).isSubsetOf(new Set([5, 4, 3, 2, 1]));
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox117: false,
+ firefox118: {
+ val: 'flagged',
+ note_id: 'ff-new-set-methods',
+ },
+ firefox127: true,
+ chrome77: false,
+ chrome122: true,
+ safari17: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm21_3_3: graalvm.newSetMethodsFlag,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Set.prototype.isSupersetOf()',
+ exec() {
+ /*
+ return new Set([5, 4, 3, 2, 1]).isSupersetOf(new Set([1, 2, 3]));
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox2: false,
+ firefox117: false,
+ firefox118: {
+ val: 'flagged',
+ note_id: 'ff-new-set-methods',
+ },
+ firefox127: true,
+ chrome77: false,
+ chrome122: true,
+ safari17: true,
+ duktape2_0: false,
+ graalvm19: false,
+ graalvm21_3_3: graalvm.newSetMethodsFlag,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'RegExp Pattern Modifiers',
+ category: '2025 features',
+ significance: 'medium',
+ spec: 'https://github.com/tc39/proposal-regexp-modifiers',
+ subtests: [
+ {
+ name: 'i flag',
+ exec() {
+ /*
+ const regex = /^[a-z](?-i:[a-z])$/i;
+ return regex.test("ab") && regex.test("Ab") && !regex.test("aB");
+ */
+ },
+ res: {
+ chrome121: false,
+ chrome122: chrome.harmony,
+ chrome124: chrome.harmony,
+ chrome125: true,
+ firefox127: false,
+ firefox129: false,
+ firefox130: {
+ val: 'flagged',
+ note_id: 'ff-regexp-modidiers',
+ note_html:
+ 'The feature has to be enabled via javascript.options.experimental.regexp_modifiers
setting under about:config
.',
+ },
+ firefox132: true,
+ safari17_5: false,
+ },
+ },
+ {
+ name: 'm flag',
+ exec() {
+ /*
+ const regex = /^a|(?m:^b)/;
+ return regex.test("a") && regex.test("b") && regex.test("c\nb") && !regex.test("c\na");
+ */
+ },
+ res: {
+ chrome121: false,
+ chrome122: chrome.harmony,
+ chrome124: chrome.harmony,
+ chrome125: true,
+ firefox127: false,
+ firefox129: false,
+ firefox130: {
+ val: 'flagged',
+ note_id: 'ff-regexp-modidiers',
+ },
+ firefox132: true,
+ safari17_5: false,
+ },
+ },
+ {
+ name: 's flag',
+ exec() {
+ /*
+ const regex = /.(?-s:.)/s;
+ return regex.test("\na") && regex.test("aa") && !regex.test("\n\n");
+ */
+ },
+ res: {
+ chrome121: false,
+ chrome122: chrome.harmony,
+ chrome124: chrome.harmony,
+ chrome125: true,
+ firefox127: false,
+ firefox129: false,
+ firefox130: {
+ val: 'flagged',
+ note_id: 'ff-regexp-modidiers',
+ },
+ firefox132: true,
+ safari17_5: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Iterator Helpers',
+ category: '2025 features',
+ significance: 'large',
+ spec: 'https://github.com/tc39/proposal-iterator-helpers',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator#iterator_helpers',
+ subtests: [
+ {
+ name: 'instanceof Iterator',
+ exec() {
+ /*
+ return [1, 2, 3].values() instanceof Iterator;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ note_html:
+ 'The feature is only available on Nightly builds, and has to be enabled via javascript.options.experimental.iterator_helpers
setting under about:config
.',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'extends Iterator',
+ exec() {
+ /*
+ class Class extends Iterator { }
+ const instance = new Class();
+ return instance[Symbol.iterator]() === instance;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.from, iterable',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/from',
+ exec() {
+ /*
+ const iterator = Iterator.from([1, 2, 3]);
+ return 'next' in iterator
+ && iterator instanceof Iterator
+ && Array.from(iterator).join() === '1,2,3';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.from, iterator',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/from',
+ exec() {
+ /*
+ const iterator = Iterator.from({
+ i: 0,
+ next() {
+ return { value: ++this.i, done: this.i > 3 };
+ }
+ });
+ return 'next' in iterator
+ && iterator instanceof Iterator
+ && Array.from(iterator).join() === '1,2,3';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.drop',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/drop',
+ exec() {
+ /*
+ return Array.from([1, 2, 3].values().drop(1)).join() === '2,3';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.every',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/every',
+ exec() {
+ /*
+ return [1, 2, 3].values().every(it => typeof it === 'number');
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.filter',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/filter',
+ exec() {
+ /*
+ return Array.from([1, 2, 3].values().filter(it => it % 2)).join() === '1,3';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.find',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/find',
+ exec() {
+ /*
+ return [1, 2, 3].values().find(it => it % 2) === 1;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.flatMap',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/flatMap',
+ exec() {
+ /*
+ return Array.from([1, 2, 3].values().flatMap(it => [it, 0])).join() === '1,0,2,0,3,0';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.forEach',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/forEach',
+ exec() {
+ /*
+ let result = '';
+ [1, 2, 3].values().forEach(it => result += it);
+ return result === '123';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.map',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/map',
+ exec() {
+ /*
+ return Array.from([1, 2, 3].values().map(it => it * it)).join() === '1,4,9';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.reduce',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/reduce',
+ exec() {
+ /*
+ return [1, 2, 3].values().reduce((a, b) => a + b) === 6;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.some',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/some',
+ exec() {
+ /*
+ return [1, 2, 3].values().some(it => typeof it === 'number');
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.take',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/take',
+ exec() {
+ /*
+ return Array.from([1, 2, 3].values().take(2)).join() === '1,2';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype.toArray',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Iterator/toArray',
+ exec() {
+ /*
+ const array = [1, 2, 3].values().toArray();
+ return Array.isArray(array) && array.join() === '1,2,3';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Iterator.prototype[@@toStringTag]',
+ exec() {
+ /*
+ return Iterator.prototype[Symbol.toStringTag] === 'Iterator';
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ firefox10: false,
+ firefox60: false,
+ firefox116: false,
+ firefox117: {
+ val: 'flagged',
+ note_id: 'ff-iterator-helpers',
+ },
+ firefox131: true,
+ chrome77: false,
+ chrome126: true,
+ duktape2_0: false,
+ graalvm21_3_3: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Promise.try',
+ category: '2025 features',
+ significance: 'tiny',
+ spec: 'https://github.com/tc39/proposal-promise-try',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/try',
+ exec() {
+ /*
+ var called = false;
+ var argsMatch = false;
+ var p = Promise.try(function () { called = true; })
+ var p2 = Promise.try(function () {
+ 'use strict';
+ argsMatch = this === undefined && arguments.length === 2 && args[0] === p && args[1] === 2;
+ }, [p, 2]);
+
+ return p instanceof Promise && called && argsMatch;
+ */
+ },
+ res: {
+ ie11: false,
+ chrome128: true,
+ firefox115: false,
+ firefox131: false,
+ firefox132: {
+ val: 'flagged',
+ note_id: 'ff-promise-try',
+ note_html:
+ 'The feature is only available on Nightly builds, and has to be enabled via javascript.options.experimental.promise_try
setting under about:config
.',
+ },
+ firefox134: true,
+ node23: true,
+ },
+ },
+]
diff --git a/developer-extension/src/panel/components/tabs/diagnosticTab/data/es5.ts b/developer-extension/src/panel/components/tabs/diagnosticTab/data/es5.ts
new file mode 100644
index 0000000000..c55923b722
--- /dev/null
+++ b/developer-extension/src/panel/components/tabs/diagnosticTab/data/es5.ts
@@ -0,0 +1,2498 @@
+/* eslint-disable */
+// @ts-nocheck
+
+const sparseNote = null
+const hermes = {}
+
+export const data = [
+ {
+ name: 'Object/array literal extensions',
+ significance: 'large',
+ subtests: [
+ {
+ name: 'Getter accessors',
+ exec() {
+ /*
+ return ({ get x(){ return 1 } }).x === 1;
+ */
+ },
+ res: {
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Setter accessors',
+ exec() {
+ /*
+ var value = 0;
+ ({ set x(v){ value = v; } }).x = 1;
+ return value === 1;
+ */
+ },
+ res: {
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Trailing commas in object literals',
+ exec() {
+ /*
+ return { a: true, }.a === true;
+ */
+ },
+ res: {
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: null,
+ chrome7: true,
+ opera10_50: true,
+ opera12_10: true,
+ konq4_3: null,
+ besen: null,
+ rhino1_7_13: true,
+ ejs: null,
+ android4_0: null,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Trailing commas in array literals',
+ exec() {
+ /*
+ return [1,].length === 1;
+ */
+ },
+ res: {
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: null,
+ chrome7: true,
+ opera10_50: true,
+ opera12_10: true,
+ konq4_3: null,
+ besen: null,
+ rhino1_7_13: true,
+ ejs: null,
+ android4_0: null,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Reserved words as property names',
+ exec() {
+ /*
+ return ({ if: 1 }).if === 1;
+ */
+ },
+ res: {
+ ie9: true,
+ firefox2: true,
+ safari5_1: true,
+ chrome5: false,
+ chrome6: false,
+ chrome7: true,
+ chrome13: true,
+ chrome19: true,
+ chrome23: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ ],
+ separator: 'after',
+ },
+ {
+ name: 'Object static methods',
+ significance: 'large',
+ subtests: [
+ {
+ name: 'Object.create',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create',
+ exec() {
+ return typeof Object.create === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.defineProperty',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperty',
+ exec() {
+ return typeof Object.defineProperty === 'function'
+ },
+ res: {
+ ie8: {
+ val: true,
+ note_id: 'define-property-ie',
+ note_html:
+ 'In Internet Explorer 8 Object.defineProperty
only accepts DOM objects ' +
+ '(MSDN reference).',
+ },
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ firefox21: true,
+ safari4: {
+ val: true,
+ note_id: 'define-property-webkit',
+ note_html:
+ 'In some versions of Safari 5, Object.defineProperty
does not work with DOM objects.',
+ },
+ safari5_1: true,
+ chrome5: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.defineProperties',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/defineProperties',
+ exec() {
+ return typeof Object.defineProperties === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.getPrototypeOf',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf',
+ exec() {
+ return typeof Object.getPrototypeOf === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox3_5: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_3: false,
+ konq4_9: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.keys',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys',
+ exec() {
+ return typeof Object.keys === 'function'
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_3: false,
+ konq4_9: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.seal',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal',
+ exec() {
+ return typeof Object.seal === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome6: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.freeze',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze',
+ exec() {
+ return typeof Object.freeze === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome6: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.preventExtensions',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions',
+ exec() {
+ return typeof Object.preventExtensions === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome6: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.isSealed',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed',
+ exec() {
+ return typeof Object.isSealed === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome6: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.isFrozen',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen',
+ exec() {
+ return typeof Object.isFrozen === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome6: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.isExtensible',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible',
+ exec() {
+ return typeof Object.isExtensible === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome6: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.getOwnPropertyDescriptor',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor',
+ exec() {
+ return typeof Object.getOwnPropertyDescriptor === 'function'
+ },
+ res: {
+ ie7: false,
+ ie8: {
+ val: true,
+ note_id: 'get-own-property-descriptor-ie',
+ note_html:
+ 'In Internet Explorer 8 Object.getOwnPropertyDescriptor
only accepts DOM objects ' +
+ '(MSDN reference).',
+ },
+ ie9: true,
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.getOwnPropertyNames',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames',
+ exec() {
+ return typeof Object.getOwnPropertyNames === 'function'
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_3: false,
+ konq4_9: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ separator: 'after',
+ },
+ ],
+ },
+ {
+ name: 'Array methods',
+ significance: 'large',
+ subtests: [
+ {
+ name: 'Array.isArray',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray',
+ exec() {
+ return typeof Array.isArray === 'function'
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: true,
+ konq4_3: false,
+ konq4_9: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.indexOf',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf',
+ exec() {
+ return typeof Array.prototype.indexOf === 'function'
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.lastIndexOf',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/lastIndexOf',
+ exec() {
+ return typeof Array.prototype.lastIndexOf === 'function'
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.every',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every',
+ exec() {
+ return typeof Array.prototype.every === 'function'
+ },
+ res: {
+ es5shim: sparseNote,
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.some',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some',
+ exec() {
+ return typeof Array.prototype.some === 'function'
+ },
+ res: {
+ es5shim: sparseNote,
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.forEach',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach',
+ exec() {
+ return typeof Array.prototype.forEach === 'function'
+ },
+ res: {
+ es5shim: sparseNote,
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.map',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map',
+ exec() {
+ return typeof Array.prototype.map === 'function'
+ },
+ res: {
+ es5shim: sparseNote,
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.filter',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter',
+ exec() {
+ return typeof Array.prototype.filter === 'function'
+ },
+ res: {
+ es5shim: sparseNote,
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.reduce',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce',
+ exec() {
+ return typeof Array.prototype.reduce === 'function'
+ },
+ res: {
+ es5shim: sparseNote,
+ ie9: true,
+ firefox2: false,
+ firefox3: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.reduceRight',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight',
+ exec() {
+ return typeof Array.prototype.reduceRight === 'function'
+ },
+ res: {
+ es5shim: sparseNote,
+ ie9: true,
+ firefox2: false,
+ firefox3: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.sort: compareFn must be function or undefined',
+ exec() {
+ try {
+ ;[1, 2].sort(null)
+ return false
+ } catch (enull) {}
+ try {
+ ;[1, 2].sort(true)
+ return false
+ } catch (etrue) {}
+ try {
+ ;[1, 2].sort({})
+ return false
+ } catch (eobj) {}
+ try {
+ ;[1, 2].sort([])
+ return false
+ } catch (earr) {}
+ try {
+ ;[1, 2].sort(/a/g)
+ return false
+ } catch (eregex) {}
+ return true
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: false,
+ firefox5: true,
+ safari1: false,
+ safari10_1: true,
+ safari11: false,
+ safari12: true,
+ safaritp: true,
+ chrome1: false,
+ chrome63: true,
+ opera10_10: null,
+ opera10_50: true,
+ konq4_3: null,
+ konq4_9: null,
+ konq4_13: null,
+ besen: null,
+ rhino1_7_13: true,
+ ejs: null,
+ android4_0: false,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.sort: compareFn may be explicit undefined',
+ exec() {
+ try {
+ const arr = [2, 1]
+ return arr.sort(undefined) === arr && arr[0] === 1 && arr[1] === 2
+ } catch (e) {
+ return false
+ }
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari3_1: true,
+ chrome13: true,
+ opera10_10: null,
+ opera10_50: true,
+ konq4_3: null,
+ konq4_9: null,
+ konq4_13: null,
+ besen: null,
+ rhino1_7_13: true,
+ ejs: null,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Array.prototype.unshift: [].unshift(0) returns the unshifted count',
+ exec() {
+ return [].unshift(0) === 1
+ },
+ res: {
+ es5shim: true,
+ chrome15: true,
+ chrome101: true,
+ firefox3: true,
+ firefox100: true,
+ ie6: false,
+ ie7: false,
+ ie8: true,
+ ie11: true,
+ opera10_60: true,
+ opera11: true,
+ opera12_10: true,
+ opera12: true,
+ safari4: true,
+ safari15: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'String properties and methods',
+ significance: 'small',
+ subtests: [
+ {
+ name: 'Property access on strings',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String#Character_access',
+ exec() {
+ return 'foobar'[3] === 'b'
+ },
+ res: {
+ ie7: false,
+ ie8: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'String.prototype.split',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split',
+ exec() {
+ // all of these tests reflect bugs that es5-shim patches
+ return (
+ typeof String.prototype.split === 'function' &&
+ ''.split().length === 1 &&
+ ''.split()[0] === '' &&
+ ''.split(undefined).length === 1 &&
+ ''.split(undefined)[0] === '' &&
+ 'ab'.split().length === 1 &&
+ 'ab'.split()[0] === 'ab' &&
+ 'ab'.split(undefined).length === 1 &&
+ 'ab'.split(undefined)[0] === 'ab' &&
+ '0'.split(undefined, 0).length === 0 &&
+ 'ab'.split(/(?:ab)*/).length === 2 &&
+ '.'.split(/(.?)(.?)/).length === 4 &&
+ 'tesst'.split(/(s)*/)[1] !== 't' &&
+ 'test'.split(/(?:)/, -1).length === 4 &&
+ ''.split(/.?/).length === 0 &&
+ '.'.split(/()()/).length === 1
+ )
+ },
+ res: {
+ chrome15: true,
+ chrome37: true,
+ edge15: true,
+ edge18: true,
+ edge80: true,
+ es5shim: true,
+ firefox3: false,
+ firefox3_6: false,
+ firefox4: false,
+ firefox5: true,
+ firefox10: true,
+ ie8: false,
+ ie9: true,
+ node0_4: true,
+ node0_6: true,
+ node0_8: false,
+ node0_10: false,
+ node0_12: true,
+ opera10_60: false,
+ opera11: true,
+ safari4: false,
+ safari5: false,
+ safari5_1: true,
+ safari13: true,
+ duktape2_0: true,
+ graalvm20_3: true,
+ jerryscript1_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'String.prototype.substr',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/substr',
+ exec() {
+ return '0b'.substr(-1) === 'b'
+ },
+ res: {
+ es5shim: true,
+ ie6: false,
+ ie7: false,
+ ie8: false,
+ ie9: true,
+ chrome15: true,
+ firefox3: true,
+ opera11: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'String.prototype.trim',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/Trim',
+ exec() {
+ return typeof String.prototype.trim === 'function'
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: false,
+ firefox3_5: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: true,
+ konq4_3: false,
+ konq4_9: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ separator: 'after',
+ },
+ ],
+ },
+ {
+ name: 'Date methods',
+ significance: 'small',
+ subtests: [
+ {
+ name: 'Date.prototype.toISOString',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toISOString',
+ exec() {
+ return typeof Date.prototype.toISOString === 'function'
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: false,
+ firefox3_5: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: false,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Date.now',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/now',
+ exec() {
+ return typeof Date.now === 'function'
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Date.prototype.toJSON',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/toJSON',
+ exec() {
+ try {
+ return Date.prototype.toJSON.call(new Date(NaN)) === null
+ } catch (e) {
+ return false
+ }
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari10: true,
+ chrome5: true,
+ opera10_10: false,
+ opera10_50: false,
+ opera12: {
+ val: false,
+ note_id: 'Date.prototype.toJSON-OP11_60-OP11_64',
+ note_html: 'In Opera 11.60-11.64 Date.prototype.toJSON is undefined.',
+ },
+ opera12_10: true,
+ konq4_3: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Function.prototype.bind',
+ significance: 'medium',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/bind',
+ exec() {
+ return typeof Function.prototype.bind === 'function'
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome7: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'JSON',
+ significance: 'medium',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/JSON',
+ exec() {
+ return typeof JSON === 'object'
+ },
+ res: {
+ ie7: false,
+ ie8: true,
+ ie9: true,
+ ie10: true,
+ firefox2: false,
+ firefox3_5: true,
+ safari4: true,
+ chrome5: true,
+ opera10_50: true,
+ konq4_3: false,
+ konq4_9: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ separator: 'after',
+ },
+ {
+ name: 'Immutable globals',
+ significance: 'small',
+ subtests: [
+ {
+ name: 'undefined',
+ exec() {
+ /*
+ undefined = 12345;
+ var result = typeof undefined === 'undefined';
+ undefined = void 0;
+ return result;
+ */
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari4: true,
+ chrome19: true,
+ chrome23: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_3: false,
+ konq4_9: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: false,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'NaN',
+ exec() {
+ /*
+ NaN = false;
+ var result = typeof NaN === 'number';
+ NaN = Math.sqrt(-1);
+ return result;
+ */
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari4: true,
+ chrome19: true,
+ chrome23: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_3: false,
+ konq4_9: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: false,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Infinity',
+ exec() {
+ /*
+ Infinity = false;
+ var result = typeof Infinity === 'number';
+ Infinity = 1/0;
+ return result;
+ */
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari4: true,
+ chrome19: true,
+ chrome23: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_3: false,
+ konq4_9: true,
+ konq4_13: true,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: false,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Number methods',
+ significance: 'small',
+ subtests: [
+ {
+ name: 'Number.prototype.toExponential rounds properly',
+ exec() {
+ return (
+ (-6.9e-11).toExponential(4) === '-6.9000e-11' && // Edge <= 17
+ (25).toExponential(0) === '3e+1' && // FF <= 86
+ (1.255).toExponential(2) === '1.25e+0'
+ ) // IE <= 11 && Edge <= 14
+ },
+ res: {
+ ie6: false,
+ ie7: false,
+ ie8: false,
+ ie9: false,
+ ie10: false,
+ ie11: false,
+ chrome15: true,
+ firefox3: true,
+ firefox3_6: false,
+ firefox86: false,
+ firefox87: true,
+ opera10_10: true,
+ safari4: true,
+ edge13: false,
+ edge14: false,
+ edge15: false,
+ edge16: false,
+ edge17: false,
+ edge18: true,
+ edge80: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Number.prototype.toExponential throws on ±Infinity fractionDigits',
+ exec() {
+ try {
+ ;(1).toExponential(Infinity)
+ ;(1).toExponential(-Infinity)
+ return false
+ } catch (e) {
+ return true
+ }
+ },
+ res: {
+ ie6: false,
+ ie7: false,
+ ie8: false,
+ ie9: true,
+ ie10: true,
+ ie11: true,
+ chrome15: true,
+ firefox3: true,
+ opera10_10: true,
+ safari4: true,
+ edge15: true,
+ edge16: true,
+ edge17: true,
+ edge18: true,
+ edge80: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Number.prototype.toExponential does not throw on edge cases',
+ exec() {
+ try {
+ NaN.toExponential(Infinity)
+ Infinity.toExponential(Infinity)
+ return true
+ } catch (e) {
+ return false
+ }
+ },
+ res: {
+ chrome37: true,
+ firefox3: false,
+ firefox3_6: false,
+ firefox49: false,
+ firefox50: true,
+ ie6: true,
+ ie8: true,
+ edge12: true,
+ safari10: false,
+ safari11: true,
+ duktape2_0: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_14: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Miscellaneous',
+ significance: 'medium',
+ subtests: [
+ {
+ name: 'Function.prototype.apply permits array-likes',
+ exec() {
+ try {
+ return function (a, b) {
+ return a === 1 && b === 2
+ }.apply({}, { 0: 1, 1: 2, length: 2 })
+ } catch (e) {
+ return false
+ }
+ },
+ res: {
+ ie7: null,
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari3_1: false,
+ safari5_1: true,
+ chrome5: false,
+ chrome13: true,
+ opera10_10: null,
+ opera10_50: true,
+ konq4_3: null,
+ besen: null,
+ rhino1_7_13: true,
+ ejs: null,
+ android4_0: null,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'parseInt ignores leading zeros',
+ exec() {
+ return parseInt('010') === 10
+ },
+ res: {
+ es5shim: true,
+ ie9: true,
+ firefox2: false,
+ firefox21: true,
+ safari6: true,
+ chrome23: true,
+ opera10_10: false,
+ opera10_50: false,
+ konq4_3: false,
+ konq4_9: false,
+ konq4_13: false,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_4: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Function "prototype" property is non-enumerable',
+ exec() {
+ /*
+ return !Function().propertyIsEnumerable('prototype');
+ */
+ },
+ res: {
+ ie7: null,
+ ie9: true,
+ firefox2: false,
+ firefox3_6: true,
+ safari5_1: true,
+ chrome5: false,
+ chrome13: true,
+ opera10_10: null,
+ opera10_50: false,
+ opera12: true,
+ konq4_3: null,
+ besen: null,
+ rhino1_7_13: true,
+ ejs: null,
+ android4_0: null,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Arguments toStringTag is "Arguments"',
+ exec() {
+ /*
+ return (function(){ return Object.prototype.toString.call(arguments) === '[object Arguments]'; }());
+ */
+ },
+ res: {
+ ie7: null,
+ ie9: true,
+ firefox2: false,
+ firefox4: true,
+ safari3_1: true,
+ chrome5: null,
+ chrome7: true,
+ chrome13: true,
+ opera10_10: null,
+ opera10_50: false,
+ opera12: true,
+ konq4_3: null,
+ besen: null,
+ rhino1_7_13: true,
+ ejs: null,
+ android4_0: null,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Zero-width chars in identifiers',
+ exec() {
+ /*
+ var _\u200c\u200d = true;
+ return _\u200c\u200d;
+ */
+ },
+ res: {
+ ie9: true,
+ firefox2: false,
+ firefox3_5: false,
+ firefox8: true,
+ firefox21: true,
+ safari6: true,
+ chrome19: true,
+ chrome23: true,
+ opera10_10: false,
+ opera10_50: false,
+ opera12_10: true,
+ konq4_3: false,
+ konq4_9: false,
+ konq4_13: false,
+ besen: true,
+ rhino1_7_13: true,
+ ejs: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Unreserved words',
+ exec() {
+ /*
+ var abstract, boolean, byte, char, double, final, float, goto, int, long,
+ native, short, synchronized, transient, volatile;
+ return true;
+ */
+ },
+ res: {
+ ie7: null,
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: false,
+ chrome13: true,
+ opera10_10: null,
+ opera10_50: true,
+ konq4_3: null,
+ besen: null,
+ rhino1_7_13: true,
+ ejs: null,
+ android4_0: null,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Enumerable properties can be shadowed by non-enumerables',
+ exec() {
+ /*
+ var result = true;
+ Object.prototype.length = 42;
+ for (var i in Function) {
+ if (i === 'length') {
+ result = false;
+ }
+ }
+ delete Object.prototype.length;
+ return result;
+ */
+ },
+ res: {
+ ie7: null,
+ ie9: false,
+ edge13: true,
+ firefox2: true,
+ safari3_1: false,
+ safari14_1: true,
+ safaritp: true,
+ chrome5: false,
+ chrome13: false,
+ chrome54: true,
+ opera10_10: null,
+ opera10_50: true,
+ konq4_3: null,
+ besen: null,
+ rhino1_7_13: false,
+ ejs: null,
+ android4_0: null,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: false,
+ jerryscript2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ {
+ name: 'Thrown functions have proper "this" values',
+ exec() {
+ /*
+ try {
+ throw function() { return !('a' in this); };
+ }
+ catch(e) {
+ var a = true;
+ return e();
+ }
+ */
+ },
+ res: {
+ ie7: null,
+ ie9: true,
+ firefox2: true,
+ safari3_1: true,
+ chrome5: true,
+ opera10_10: null,
+ opera10_50: true,
+ konq4_3: null,
+ besen: null,
+ rhino1_7_13: true,
+ ejs: null,
+ android4_0: null,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Strict mode',
+ significance: 'large',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Strict_mode',
+ subtests: [
+ {
+ name: 'reserved words',
+ exec() {
+ /*
+ 'use strict';
+ var words = 'implements,interface,let,package,private,protected,public,static,yield'.split(',');
+ for (var i = 0; i < 9; i+=1) {
+ try { eval('var ' + words[i]); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ }
+ return true;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: hermes.evalStrictMode,
+ reactnative0_70_3: false,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '"this" is undefined in functions',
+ exec() {
+ /*
+ 'use strict';
+ return this === void undefined && (function(){ return this === void undefined; }).call();
+ */
+ },
+ res: {
+ ie10: {
+ val: true,
+ note_id: 'strict-mode-ie10',
+ note_html: 'IE10 PP2 fails this test.',
+ },
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"this" is not coerced to object in primitive methods',
+ exec() {
+ /*
+ 'use strict';
+ return (function(){ return typeof this === 'string' }).call('')
+ && (function(){ return typeof this === 'number' }).call(1)
+ && (function(){ return typeof this === 'boolean' }).call(true);
+ */
+ },
+ res: {
+ ie10: true,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"this" is not coerced to object in primitive accessors',
+ exec() {
+ /*
+ 'use strict';
+
+ function test(Class, instance) {
+ Object.defineProperty(Class.prototype, 'test', {
+ get: function () { passed = passed && this === instance; },
+ set: function () { passed = passed && this === instance; },
+ configurable: true
+ });
+
+ var passed = true;
+ instance.test;
+ instance.test = 42;
+ return passed;
+ }
+
+ return test(String, '')
+ && test(Number, 1)
+ && test(Boolean, true);
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox46: true,
+ safari6: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12_10: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript1_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'legacy octal is a SyntaxError',
+ exec() {
+ /*
+ 'use strict';
+ try { eval('010'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ try { eval('"\\010"'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ return true;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: hermes.evalStrictMode,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'assignment to unresolvable identifiers is a ReferenceError',
+ exec() {
+ /*
+ 'use strict';
+ try { eval('__i_dont_exist = 1'); } catch (err) { return err instanceof ReferenceError; }
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: hermes.evalStrictMode,
+ reactnative0_70_3: false,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'assignment to eval or arguments is a SyntaxError',
+ exec() {
+ /*
+ 'use strict';
+ try { eval('eval = 1'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ try { eval('arguments = 1'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ try { eval('eval++'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ try { eval('arguments++'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ return true;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: hermes.evalStrictMode,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'assignment to non-writable properties is a TypeError',
+ exec() {
+ /*
+ 'use strict';
+ try { Object.defineProperty({},"x",{ writable: false }).x = 1; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }
+ try { Object.preventExtensions({}).x = 1; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }
+ try { ({ get x(){ } }).x = 1; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }
+ try { (function f() { f = 123; })(); return false; } catch (err) { if (!(err instanceof TypeError)) return false; }
+ return true;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript1_0: false,
+ jerryscript2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'eval or arguments bindings is a SyntaxError',
+ exec() {
+ /*
+ 'use strict';
+ try { eval('var eval'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ try { eval('var arguments'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ try { eval('(function(eval){})'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ try { eval('(function(arguments){})'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ try { eval('try{}catch(eval){}'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ try { eval('try{}catch(arguments){}'); return false; } catch (err) { if (!(err instanceof SyntaxError)) return false; }
+ return true;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: hermes.evalStrictMode,
+ reactnative0_70_3: false,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'arguments.caller removed or is a TypeError',
+ exec() {
+ /*
+ 'use strict';
+ if ('caller' in arguments) {
+ try { arguments.caller; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }
+ }
+ return true;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari3_1: true,
+ chrome13: true,
+ opera10_50: true,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'arguments.callee is a TypeError',
+ exec() {
+ /*
+ 'use strict';
+ try { arguments.callee; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }
+ return true;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '(function(){}).caller and (function(){}).arguments is a TypeError',
+ exec() {
+ /*
+ 'use strict';
+ try { (function(){}).caller; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }
+ try { (function(){}).arguments; return false; } catch (err) { if (!(err instanceof TypeError)) return false; }
+ return true;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'arguments is unmapped',
+ exec() {
+ /*
+ 'use strict';
+ return (function(x){
+ x = 2;
+ return arguments[0] === 1;
+ })(1) && (function(x){
+ arguments[0] = 2;
+ return x === 1;
+ })(1);
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: false,
+ },
+ },
+ {
+ name: "eval() can't create bindings",
+ exec() {
+ /*
+ 'use strict';
+ try { eval('var __some_unique_variable;'); __some_unique_variable; } catch (err) { return err instanceof ReferenceError; }
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: hermes.evalLexicalScopeSuccess,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'deleting bindings is a SyntaxError',
+ exec() {
+ /*
+ 'use strict';
+ try { eval('var x; delete x;'); } catch (err) { return err instanceof SyntaxError; }
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: hermes.evalStrictMode,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'deleting non-configurable properties is a TypeError',
+ exec() {
+ /*
+ 'use strict';
+ try { delete Object.prototype; } catch (err) { return err instanceof TypeError; }
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '"with" is a SyntaxError',
+ exec() {
+ /*
+ 'use strict';
+ try { eval('with({}){}'); } catch (err) { return err instanceof SyntaxError; }
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'repeated parameter names is a SyntaxError',
+ exec() {
+ /*
+ 'use strict';
+ try { eval('function f(x, x) { }'); } catch (err) { return err instanceof SyntaxError; }
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ safari5_1: true,
+ chrome13: true,
+ opera10_50: false,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: hermes.evalStrictMode,
+ reactnative0_70_3: false,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'function expressions with matching name and argument are valid',
+ exec() {
+ /*
+ var foo = function bar(bar) {'use strict'};
+ return typeof foo === 'function';
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: true,
+ safari3_1: true,
+ safari5_1: false,
+ safari10: true,
+ safari11: false,
+ safari11_1: true,
+ chrome13: true,
+ opera10_50: true,
+ opera12: true,
+ besen: true,
+ phantom1_9: true,
+ ejs: true,
+ ios7: true,
+ ios8: true,
+ ios9: true,
+ android4_1: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: false,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+]
diff --git a/developer-extension/src/panel/components/tabs/diagnosticTab/data/es6.ts b/developer-extension/src/panel/components/tabs/diagnosticTab/data/es6.ts
new file mode 100644
index 0000000000..ddc1a4a0b5
--- /dev/null
+++ b/developer-extension/src/panel/components/tabs/diagnosticTab/data/es6.ts
@@ -0,0 +1,26040 @@
+/* eslint-disable */
+// @ts-nocheck
+
+const babel = {}
+const typescript = {}
+const chrome = {}
+const edge = {}
+const safari = {}
+const graalvm = {}
+const hermes = {}
+
+export const data = [
+ {
+ name: 'proper tail calls (tail call optimisation)',
+ category: 'optimisation',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-tail-position-calls',
+ note_id: 'proper-tail-calls',
+ note_html:
+ '' +
+ 'The feature can be enabled with use strict
and JavaScript flag "--harmony-tailcalls"
' +
+ 'in certain versions of Node.js. Since Node.js 8.2.1, the V8 flags ' +
+ '--harmony-tailcalls
and --harmony-explicit-tailcalls
' +
+ 'have been removed. See: ' +
+ 'Chrome Platform Status, ' +
+ '' +
+ 'blog in JavaScript in Plain English, ' +
+ 'and V8 Dev Blog for details.',
+ subtests: [
+ {
+ name: 'direct recursion',
+ exec() {
+ /*
+ "use strict";
+ return (function f(n){
+ if (n <= 0) {
+ return "foo";
+ }
+ return f(n - 1);
+ }(1e6)) === "foo";
+ */
+ },
+ res: {
+ tr: {
+ val: 'flagged',
+ note_id: 'tr-tco',
+ note_html: 'Requires the properTailCalls
compile option.',
+ },
+ babel6corejs2: false,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ firefox2: false,
+ opera10_50: false,
+ chrome51: chrome.harmony,
+ chrome58: chrome.tco,
+ chrome61: false,
+ safari10: true,
+ xs6: true,
+ duktape2_0: true,
+ graalvm19: false,
+ jerryscript2_0: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: false,
+ },
+ },
+ {
+ name: 'mutual recursion',
+ exec() {
+ /*
+ "use strict";
+ function f(n){
+ if (n <= 0) {
+ return "foo";
+ }
+ return g(n - 1);
+ }
+ function g(n){
+ if (n <= 0) {
+ return "bar";
+ }
+ return f(n - 1);
+ }
+ return f(1e6) === "foo" && f(1e6+1) === "bar";
+ */
+ },
+ res: {
+ tr: { val: 'flagged', note_id: 'tr-tco' },
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ firefox2: false,
+ opera10_50: false,
+ chrome51: chrome.harmony,
+ chrome58: chrome.tco,
+ chrome61: false,
+ safari10: true,
+ xs6: true,
+ duktape2_0: true,
+ graalvm19: false,
+ jerryscript2_0: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'arrow functions',
+ category: 'functions',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-arrow-function-definitions',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions',
+ subtests: [
+ {
+ name: '0 parameters',
+ exec() {
+ /*
+ return (() => 5)() === 5;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ chrome38: chrome.experimental,
+ chrome40: false,
+ chrome45: true,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '1 parameter, no brackets',
+ exec() {
+ /*
+ var b = x => x + "foo";
+ return (b("fee fie foe ") === "fee fie foe foo");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ chrome38: chrome.experimental,
+ chrome40: false,
+ chrome45: true,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'multiple parameters',
+ exec() {
+ /*
+ var c = (v, w, x, y, z) => "" + v + w + x + y + z;
+ return (c(6, 5, 4, 3, 2) === "65432");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ chrome38: chrome.experimental,
+ chrome40: false,
+ chrome45: true,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'lexical "this" binding',
+ exec() {
+ /*
+ var d = { x : "bar", y : function() { return z => this.x + z; }}.y();
+ var e = { x : "baz", y : d };
+ return d("ley") === "barley" && e.y("ley") === "barley";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ chrome45: true,
+ safari10: true,
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '"this" unchanged by call or apply',
+ exec() {
+ /*
+ var d = { x : "foo", y : function() { return () => this.x; }};
+ var e = { x : "bar" };
+ return d.y().call(e) === "foo" && d.y().apply(e) === "foo";
+ */
+ },
+ res: {
+ tr: true,
+ closure: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ chrome45: true,
+ safari10: true,
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: "can't be bound, can be curried",
+ exec() {
+ /*
+ var d = { x : "bar", y : function() { return z => this.x + z; }};
+ var e = { x : "baz" };
+ return d.y().bind(e, "ley")() === "barley";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ chrome45: true,
+ safari10: true,
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'lexical "arguments" binding',
+ exec() {
+ /*
+ var f = (function() { return z => arguments[0]; }(5));
+ return f(6) === 5;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox22: true,
+ firefox24: false,
+ firefox43: true,
+ opera10_50: false,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'no line break between params and =>
',
+ exec() {
+ /*
+ return (() => {
+ try { Function("x\n => 2")(); } catch(e) { return true; }
+ })();
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ tr: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox39: true,
+ opera10_50: false,
+ safari10: true,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'correct precedence',
+ exec() {
+ /*
+ return (() => {
+ try { Function("0 || () => 2")(); } catch(e) { return true; }
+ })();
+ */
+ },
+ res: {
+ closure: true,
+ tr: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ safari10: true,
+ chrome47: true,
+ node6: true,
+ node6_5: true,
+ xs6: false,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'no "prototype" property',
+ exec() {
+ /*
+ var a = () => 5;
+ return !a.hasOwnProperty("prototype");
+ */
+ },
+ res: {
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ chrome39: chrome.experimental,
+ chrome40: false,
+ chrome45: true,
+ safari10: true,
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'lexical "super" binding in constructors',
+ exec() {
+ /*
+ var received;
+
+ class B {
+ constructor (arg) {
+ received = arg;
+ }
+ }
+ class C extends B {
+ constructor () {
+ var callSuper = () => super('foo');
+ callSuper();
+ }
+ }
+ return new C instanceof C && received === 'foo'
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: false,
+ closure: false,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome45: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'lexical "super" binding in methods',
+ exec() {
+ /*
+ class B {
+ qux() {
+ return "quux";
+ }
+ }
+ class C extends B {
+ baz() {
+ return x => super.qux();
+ }
+ }
+ var arrow = new C().baz();
+ return arrow() === "quux";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome45: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'lexical "new.target" binding',
+ exec() {
+ /*
+ function C() {
+ return x => new.target;
+ }
+ return new C()() === C && C()() === void undefined;
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox41: true,
+ opera10_50: false,
+ chrome46: true,
+ ie11: false,
+ edge13: true,
+ node5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_2: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'const',
+ category: 'bindings',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/const',
+ subtests: [
+ {
+ name: 'basic support',
+ exec() {
+ /*
+ const foo = 123;
+ return (foo === 123);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox3: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_4: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'is block-scoped',
+ exec() {
+ /*
+ const bar = 123;
+ { const bar = 456; }
+ return bar === 123;
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'scope shadow resolution',
+ exec() {
+ /*
+ try {
+ { const bar = 456; }
+ const bar = 123;
+ return bar === 123;
+ } catch(e) {
+ return false;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox36: true,
+ chrome48: 'flagged',
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ safari10: false,
+ safari10_1: false,
+ safari11: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'cannot be in statements',
+ exec() {
+ /*
+ const bar = 1;
+ try {
+ Function("if(true) const baz = 1;")();
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'redefining a const is an error',
+ exec() {
+ /*
+ const baz = 1;
+ try {
+ Function("const foo = 1; foo = 2;")();
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for loop statement scope',
+ exec() {
+ /*
+ const baz = 1;
+ for(const baz = 0; false;) {}
+ return baz === 1;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ es6tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox36: true,
+ opera10_50: false,
+ safari10: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for-in loop iteration scope',
+ exec() {
+ /*
+ var scopes = [];
+ for(const i in { a:1, b:1 }) {
+ scopes.push(function(){ return i; });
+ }
+ return (scopes[0]() === "a" && scopes[1]() === "b");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ safari10: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for-of loop iteration scope',
+ exec() {
+ /*
+ var scopes = [];
+ for(const i of ['a','b']) {
+ scopes.push(function(){ return i; });
+ }
+ return (scopes[0]() === "a" && scopes[1]() === "b");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ safari10: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'temporal dead zone',
+ exec() {
+ /*
+ var passed = (function(){ try { qux; } catch(e) { return true; }}());
+ function fn() { passed &= qux === 456; }
+ const qux = 456;
+ fn();
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.optional,
+ ie11: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'basic support (strict mode)',
+ exec() {
+ /*
+ "use strict";
+ const foo = 123;
+ return (foo === 123);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox3: true,
+ chrome5: chrome.experimental,
+ chrome41: true,
+ safari3_1: true,
+ safari5_1: false,
+ safari10: true,
+ opera10_50: true,
+ konq4_14: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'is block-scoped (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ const bar = 123;
+ { const bar = 456; }
+ return bar === 123;
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ tr: true,
+ ejs: true,
+ closure: true,
+ chrome19: chrome.experimental,
+ chrome41: true,
+ ie11: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'scope shadow resolution (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ try {
+ { const bar = 456; }
+ const bar = 123;
+ return bar === 123;
+ } catch(e) {
+ return false;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ tr: true,
+ ejs: true,
+ closure: true,
+ chrome19: 'flagged',
+ chrome41: true,
+ ie11: true,
+ firefox2: false,
+ firefox36: true,
+ safari10: false,
+ safari10_1: false,
+ safari11: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'cannot be in statements (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ const bar = 1;
+ try {
+ Function("'use strict'; if(true) const baz = 1;")();
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ tr: true,
+ ejs: true,
+ closure: true,
+ chrome19: chrome.experimental,
+ chrome41: true,
+ ie11: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'redefining a const (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ const baz = 1;
+ try {
+ Function("'use strict'; const foo = 1; foo = 2;")();
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox7: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome41: true,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for loop statement scope (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ const baz = 1;
+ for(const baz = 0; false;) {}
+ return baz === 1;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox36: true,
+ opera10_50: false,
+ chrome19: chrome.experimental,
+ chrome41: true,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for-in loop iteration scope (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ var scopes = [];
+ for(const i in { a:1, b:1 }) {
+ scopes.push(function(){ return i; });
+ }
+ return (scopes[0]() === "a" && scopes[1]() === "b");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ chrome40: chrome.experimental,
+ chrome41: true,
+ safari10: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for-of loop iteration scope (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ var scopes = [];
+ for(const i of ['a','b']) {
+ scopes.push(function(){ return i; });
+ }
+ return (scopes[0]() === "a" && scopes[1]() === "b");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ safari10: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome40: chrome.experimental,
+ chrome41: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'temporal dead zone (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ var passed = (function(){ try { qux; } catch(e) { return true; }}());
+ function fn() { passed &= qux === 456; }
+ const qux = 456;
+ fn();
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.optional,
+ ie11: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome19: chrome.experimental,
+ chrome41: true,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'let',
+ category: 'bindings',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-let-and-const-declarations',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let',
+ subtests: [
+ {
+ name: 'basic support',
+ exec() {
+ /*
+ let foo = 123;
+ return (foo === 123);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: {
+ val: 'flagged',
+ note_id: 'fx-let',
+ note_html:
+ 'Available for code in a <script type="application/javascript;version=1.7">
(or version=1.8
) tag.',
+ },
+ firefox44: true,
+ opera10_50: false,
+ safari10: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'is block-scoped',
+ exec() {
+ /*
+ let bar = 123;
+ { let bar = 456; }
+ return bar === 123;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ opera10_50: false,
+ safari10: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'scope shadow resolution',
+ exec() {
+ /*
+ try {
+ { let bar = 456; }
+ let bar = 123;
+ return bar === 123;
+ } catch(e) {
+ return false;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ safari10: false,
+ safari10_1: false,
+ safari11: true,
+ chrome48: 'flagged',
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'cannot be in statements',
+ exec() {
+ /*
+ let bar = 1;
+ try {
+ Function("if(true) let baz = 1;")();
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ opera10_50: false,
+ safari10: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for loop statement scope',
+ exec() {
+ /*
+ let baz = 1;
+ for(let baz = 0; false;) {}
+ return baz === 1;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ es6tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ opera10_50: false,
+ safari10: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'temporal dead zone',
+ exec() {
+ /*
+ var passed = (function(){ try { qux; } catch(e) { return true; }}());
+ function fn() { passed &= qux === 456; }
+ let qux = 456;
+ fn();
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.optional,
+ ie11: true,
+ firefox2: false,
+ firefox35: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ opera10_50: false,
+ safari10: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for/for-in loop iteration scope',
+ exec() {
+ /*
+ let scopes = [];
+ for(let i = 0; i < 2; i++) {
+ scopes.push(function(){ return i; });
+ }
+ let passed = (scopes[0]() === 0 && scopes[1]() === 1);
+
+ scopes = [];
+ for(let i in { a:1, b:1 }) {
+ scopes.push(function(){ return i; });
+ }
+ passed &= (scopes[0]() === "a" && scopes[1]() === "b");
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ safari10: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for-in loop binding shadowing parameter',
+ exec() {
+ /*
+ try {
+ Function("function f(e) { for (let e in {}) e }");
+ return true;
+ } catch(e) {
+ return false;
+ }
+ */
+ },
+ res: {
+ closure: true,
+ ie11: true,
+ edge14: true,
+ firefox2: false,
+ firefox3: false,
+ firefox3_6: false,
+ firefox4: true,
+ firefox5: true,
+ firefox10: true,
+ firefox20: true,
+ firefox30: true,
+ firefox40: true,
+ firefox44: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ safari10_1: false,
+ safari11: true,
+ node6: true,
+ duktape2_0: false,
+ jerryscript2_2_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'basic support (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ let foo = 123;
+ return (foo === 123);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ chrome19: chrome.experimental,
+ chrome41: true,
+ node0_12: 'flagged',
+ node4: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ opera10_50: false,
+ safari10: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'is block-scoped (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ let bar = 123;
+ { let bar = 456; }
+ return bar === 123;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ opera10_50: false,
+ chrome19: chrome.experimental,
+ chrome41: true,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'scope shadow resolution (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ try {
+ { let bar = 456; }
+ let bar = 123;
+ return bar === 123;
+ } catch(e) {
+ return false;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ chrome19: 'flagged',
+ chrome41: true,
+ safari10: false,
+ safari10_1: false,
+ safari11: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'cannot be in statements (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ let bar = 1;
+ try {
+ Function("'use strict'; if(true) let baz = 1;")();
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ opera10_50: false,
+ safari10: true,
+ chrome19: chrome.experimental,
+ chrome41: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for loop statement scope (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ let baz = 1;
+ for(let baz = 0; false;) {}
+ return baz === 1;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox4: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ opera10_50: false,
+ chrome19: chrome.experimental,
+ chrome41: true,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'temporal dead zone (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ var passed = (function(){ try { qux; } catch(e) { return true; }}());
+ function fn() { passed &= qux === 456; }
+ let qux = 456;
+ fn();
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.optional,
+ ie11: true,
+ firefox2: false,
+ firefox35: { val: 'flagged', note_id: 'fx-let' },
+ firefox44: true,
+ opera10_50: false,
+ chrome19: chrome.experimental,
+ chrome41: true,
+ safari10: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for/for-in loop iteration scope (strict mode)',
+ exec() {
+ /*
+ 'use strict';
+ let scopes = [];
+ for(let i = 0; i < 2; i++) {
+ scopes.push(function(){ return i; });
+ }
+ let passed = (scopes[0]() === 0 && scopes[1]() === 1);
+
+ scopes = [];
+ for(let i in { a:1, b:1 }) {
+ scopes.push(function(){ return i; });
+ }
+ passed &= (scopes[0]() === "a" && scopes[1]() === "b");
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ chrome37: chrome.experimental,
+ chrome41: true,
+ safari10: true,
+ ie11: false,
+ edge14: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'for-in loop binding shadowing parameter (strict mode)',
+ exec() {
+ /*
+ try {
+ Function("'use strict'; function f(e) { for (let e in {}) e }");
+ return true;
+ } catch(e) {
+ return false;
+ }
+ */
+ },
+ res: {
+ closure: true,
+ ie11: true,
+ edge14: true,
+ firefox2: false,
+ firefox3: false,
+ firefox3_6: false,
+ firefox4: true,
+ firefox5: true,
+ firefox10: true,
+ firefox20: true,
+ firefox30: true,
+ firefox40: true,
+ firefox44: true,
+ opera10_50: false,
+ chrome41: true,
+ safari10_1: false,
+ safari11: true,
+ node0_12: 'flagged',
+ node4: true,
+ duktape2_0: false,
+ jerryscript2_2_0: true,
+ graalvm19: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'default function parameters',
+ category: 'syntax',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Default_parameters',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ return (function (a = 1, b = 2) { return a === 3 && b === 2; }(3));
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox15: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge14: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'explicit undefined defers to the default',
+ exec() {
+ /*
+ return (function (a = 1, b = 2) { return a === 1 && b === 3; }(undefined, 3));
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge14: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'defaults can refer to previous params',
+ exec() {
+ /*
+ return (function (a, b = a) { return b === 5; }(5));
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox15: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge14: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'arguments object interaction',
+ exec() {
+ /*
+ return (function (a = "baz", b = "qux", c = "quux") {
+ a = "corge";
+ // The arguments object is not mapped to the
+ // parameters, even outside of strict mode.
+ return arguments.length === 2
+ && arguments[0] === "foo"
+ && arguments[1] === "bar";
+ }("foo", "bar"));
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ safari10: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox43: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'temporal dead zone',
+ exec() {
+ /*
+ return (function(x = 1) {
+ try {
+ eval("(function(a=a){}())");
+ return false;
+ } catch(e) {}
+ try {
+ eval("(function(a=b,b){}())");
+ return false;
+ } catch(e) {}
+ return true;
+ }());
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ closure: true,
+ typescript1corejs2: true,
+ safari10: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'separate scope',
+ exec() {
+ /*
+ return (function(a=function(){
+ return typeof b === 'undefined';
+ }){
+ var b = 1;
+ return a();
+ }());
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ closure: true,
+ safari10: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'new Function() support',
+ exec() {
+ /*
+ return new Function("a = 1", "b = 2",
+ "return a === 3 && b === 2;"
+ )(3);
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ safari10: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: { val: false, note_id: 'ejs-no-function-ctor' },
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ jerryscript2_2_0: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'rest parameters',
+ category: 'syntax',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-function-definitions',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/rest_parameters',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ return (function (foo, ...args) {
+ return args instanceof Array && args + "" === "bar,baz";
+ }("foo", "bar", "baz"));
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox15: true,
+ opera10_50: false,
+ chrome44: chrome.experimental,
+ chrome47: true,
+ node4: 'flagged',
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: "function 'length' property",
+ exec() {
+ /*
+ return function(a, ...b){}.length === 1 && function(...c){}.length === 0;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ closure20211107: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox15: true,
+ opera10_50: false,
+ chrome44: chrome.experimental,
+ chrome47: true,
+ node4: 'flagged',
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'arguments object interaction',
+ exec() {
+ /*
+ return (function (foo, ...args) {
+ foo = "qux";
+ // The arguments object is not mapped to the
+ // parameters, even outside of strict mode.
+ return arguments.length === 3
+ && arguments[0] === "foo"
+ && arguments[1] === "bar"
+ && arguments[2] === "baz";
+ }("foo", "bar", "baz"));
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ tr: true,
+ ejs: true,
+ chrome44: chrome.experimental,
+ chrome47: true,
+ ie11: false,
+ edge12: true,
+ node4: 'flagged',
+ node6: true,
+ node6_5: true,
+ firefox2: false,
+ firefox43: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: "can't be used in setters",
+ exec() {
+ /*
+ return (function (...args) {
+ try {
+ eval("({set e(...args){}})");
+ } catch(e) {
+ return true;
+ }
+ }());
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ tr: true,
+ ejs: true,
+ closure: true,
+ jsx: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ chrome47: true,
+ node4: 'flagged',
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'new Function() support',
+ exec() {
+ /*
+ return new Function("a", "...b",
+ "return b instanceof Array && a+b === 'foobar,baz';"
+ )('foo','bar','baz');
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox15: true,
+ opera10_50: false,
+ chrome44: chrome.experimental,
+ chrome47: true,
+ node4: 'flagged',
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ ejs: { val: false, note_id: 'ejs-no-function-ctor' },
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'spread syntax for iterable objects',
+ category: 'syntax',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-argument-lists-runtime-semantics-argumentlistevaluation',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_operator',
+ subtests: [
+ {
+ name: 'with arrays, in function calls',
+ exec() {
+ /*
+ return Math.max(...[1, 2, 3]) === 3
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome44: chrome.experimental,
+ chrome46: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with arrays, in array literals',
+ exec() {
+ /*
+ return [...[1, 2, 3]][2] === 3;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox16: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome46: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with sparse arrays, in function calls',
+ exec() {
+ /*
+ var a = Array(...[,,]);
+ return "0" in a && "1" in a && '' + a[0] + a[1] === "undefinedundefined";
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome44: chrome.experimental,
+ chrome46: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with sparse arrays, in array literals',
+ exec() {
+ /*
+ var a = [...[,,]];
+ return "0" in a && "1" in a && '' + a[0] + a[1] === "undefinedundefined";
+ */
+ },
+ res: {
+ tr: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox16: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome46: true,
+ node4: 'flagged',
+ node5: true,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with strings, in function calls',
+ exec() {
+ /*
+ return Math.max(..."1234") === 4;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome44: chrome.experimental,
+ chrome46: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with strings, in array literals',
+ exec() {
+ /*
+ return ["a", ..."bcd", "e"][3] === "d";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox17: true,
+ opera10_50: false,
+ safari9: true,
+ chrome46: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with astral plane strings, in function calls',
+ exec() {
+ /*
+ return Array(..."𠮷𠮶")[0] === "𠮷";
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome44: chrome.experimental,
+ chrome46: true,
+ ie11: false,
+ edge12: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with astral plane strings, in array literals',
+ exec() {
+ /*
+ return [..."𠮷𠮶"][0] === "𠮷";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge12: true,
+ chrome46: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generator instances, in calls',
+ exec() {
+ /*
+ var iterable = (function*(){ yield 1; yield 2; yield 3; }());
+ return Math.max(...iterable) === 3;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ ejs: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome44: chrome.experimental,
+ chrome46: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generator instances, in arrays',
+ exec() {
+ /*
+ var iterable = (function*(){ yield "b"; yield "c"; yield "d"; }());
+ return ["a", ...iterable, "e"][3] === "d";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome46: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generic iterables, in calls',
+ exec() {
+ /*
+ var iterable = global.__createIterableObject([1, 2, 3]);
+ return Math.max(...iterable) === 3;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ es6tr: {
+ val: true,
+ note_id: 'compiler-iterable',
+ note_html:
+ 'This compiler requires generic iterables have either a Symbol.iterator
or non-standard "@@iterator"
method.',
+ },
+ ejs: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome44: chrome.experimental,
+ chrome46: true,
+ ie11: false,
+ edge12: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generic iterables, in arrays',
+ exec() {
+ /*
+ var iterable = global.__createIterableObject(["b", "c", "d"]);
+ return ["a", ...iterable, "e"][3] === "d";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ es6tr: { val: true, note_id: 'compiler-iterable' },
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome46: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with instances of iterables, in calls',
+ exec() {
+ /*
+ var iterable = global.__createIterableObject([1, 2, 3]);
+ return Math.max(...Object.create(iterable)) === 3;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ ejs: true,
+ es6tr: { val: true, note_id: 'compiler-iterable' },
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome44: chrome.experimental,
+ chrome46: true,
+ ie11: false,
+ edge12: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with instances of iterables, in arrays',
+ exec() {
+ /*
+ var iterable = global.__createIterableObject(["b", "c", "d"]);
+ return ["a", ...Object.create(iterable), "e"][3] === "d";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ ejs: true,
+ es6tr: { val: true, note_id: 'compiler-iterable' },
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome46: true,
+ safari9: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'spreading non-iterables is a runtime error',
+ exec() {
+ /*
+ try {
+ Math.max(...2);
+ } catch(e) {
+ return Math.max(...[1, 2, 3]) === 3;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.notDownlevelIteration,
+ closure20230228: true,
+ es6tr: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome44: chrome.experimental,
+ chrome46: true,
+ node4: 'flagged',
+ node5: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'class',
+ category: 'functions',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-class-definitions',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Classes',
+ subtests: [
+ {
+ name: 'class statement',
+ exec() {
+ /*
+ class C {}
+ return typeof C === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ ejs: true,
+ jsx: true,
+ closure: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ typescript1corejs2: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'is block-scoped',
+ exec() {
+ /*
+ class C {}
+ var c1 = C;
+ {
+ class C {}
+ var c2 = C;
+ }
+ return C === c1;
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ jsx: true,
+ closure: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'class expression',
+ exec() {
+ /*
+ return typeof class C {} === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'anonymous class',
+ exec() {
+ /*
+ return typeof class {} === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'constructor',
+ exec() {
+ /*
+ class C {
+ constructor() { this.x = 1; }
+ }
+ return C.prototype.constructor === C
+ && new C().x === 1;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'prototype methods',
+ exec() {
+ /*
+ class C {
+ method() { return 2; }
+ }
+ return typeof C.prototype.method === "function"
+ && new C().method() === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'string-keyed methods',
+ exec() {
+ /*
+ class C {
+ "foo bar"() { return 2; }
+ }
+ return typeof C.prototype["foo bar"] === "function"
+ && new C()["foo bar"]() === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed prototype methods',
+ exec() {
+ /*
+ var foo = "method";
+ class C {
+ [foo]() { return 2; }
+ }
+ return typeof C.prototype.method === "function"
+ && new C().method() === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome45: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ safari10: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'optional semicolons',
+ exec() {
+ /*
+ class C {
+ ;
+ method() { return 2; };
+ method2() { return 2; }
+ method3() { return 2; };
+ }
+ return typeof C.prototype.method === "function"
+ && typeof C.prototype.method2 === "function"
+ && typeof C.prototype.method3 === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'static methods',
+ exec() {
+ /*
+ class C {
+ static method() { return 3; }
+ }
+ return typeof C.method === "function"
+ && C.method() === 3;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed static methods',
+ exec() {
+ /*
+ var foo = "method";
+ class C {
+ static [foo]() { return 3; }
+ }
+ return typeof C.method === "function"
+ && C.method() === 3;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome45: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ safari10: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'accessor properties',
+ exec() {
+ /*
+ var baz = false;
+ class C {
+ get foo() { return "foo"; }
+ set bar(x) { baz = x; }
+ }
+ new C().bar = true;
+ return new C().foo === "foo" && baz;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ jsx: true,
+ es6tr: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed accessor properties',
+ exec() {
+ /*
+ var garply = "foo", grault = "bar", baz = false;
+ class C {
+ get [garply]() { return "foo"; }
+ set [grault](x) { baz = x; }
+ }
+ new C().bar = true;
+ return new C().foo === "foo" && baz;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome45: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ safari10: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'static accessor properties',
+ exec() {
+ /*
+ var baz = false;
+ class C {
+ static get foo() { return "foo"; }
+ static set bar(x) { baz = x; }
+ }
+ C.bar = true;
+ return C.foo === "foo" && baz;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ jsx: true,
+ es6tr: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed static accessor properties',
+ exec() {
+ /*
+ var garply = "foo", grault = "bar", baz = false;
+ class C {
+ static get [garply]() { return "foo"; }
+ static set [grault](x) { baz = x; }
+ }
+ C.bar = true;
+ return C.foo === "foo" && baz;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure20200112: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome45: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ safari10: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'class name is lexically scoped',
+ exec() {
+ /*
+ class C {
+ method() { return typeof C === "function"; }
+ }
+ var M = C.prototype.method;
+ C = void undefined;
+ return C === void undefined && M();
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ ejs: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari10: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed names, temporal dead zone',
+ exec() {
+ /*
+ try {
+ var B = class C {
+ [C](){}
+ }
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome45: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ safari10: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ hermes0_12_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: "methods aren't enumerable",
+ exec() {
+ /*
+ class C {
+ foo() {}
+ static bar() {}
+ }
+ return !C.prototype.propertyIsEnumerable("foo") && !C.propertyIsEnumerable("bar");
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ ejs: true,
+ jsx: true,
+ chrome42: 'strict',
+ chrome49: true,
+ safari9: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'implicit strict mode',
+ exec() {
+ /*
+ class C {
+ static method() { return this === void undefined; }
+ }
+ return (0,C.method)();
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'constructor requires new',
+ exec() {
+ /*
+ class C {}
+ try {
+ C();
+ }
+ catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ safari9: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'extends',
+ exec() {
+ /*
+ class B {}
+ class C extends B {}
+ return new C() instanceof B
+ && B.isPrototypeOf(C);
+ */
+ },
+ res: {
+ es6tr: {
+ val: false,
+ note_id: 'compiler-proto',
+ note_html: 'Requires native support for Object.prototype.__proto__
',
+ },
+ babel6corejs2: { val: false, note_id: 'compiler-proto' },
+ tr: { val: false, note_id: 'compiler-proto' },
+ typescript1corejs2: {
+ val: false,
+ note_id: 'typescript-extends',
+ note_html:
+ 'TypeScript transforms extends
into code that copies static properties from the superclass (but uses the prototype chain for instance properties).',
+ },
+ ejs: true,
+ closure: {
+ val: false,
+ note_id: 'compiled-extends',
+ note_html:
+ 'This compiler transforms extends
into code that uses native Object.prototype.__proto__
or copies properties from the superclass, instead of using the prototype chain.',
+ },
+ jsx: { val: false, note_id: 'compiled-extends' },
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'extends expressions',
+ exec() {
+ /*
+ var B;
+ class C extends (B = class {}) {}
+ return new C() instanceof B
+ && B.isPrototypeOf(C);
+ */
+ },
+ res: {
+ es6tr: { val: false, note_id: 'compiler-proto' },
+ babel6corejs2: { val: false, note_id: 'compiler-proto' },
+ tr: { val: false, note_id: 'compiler-proto' },
+ typescript1corejs2: {
+ val: false,
+ note_id: 'typescript-extends',
+ },
+ closure20180910: {
+ val: false,
+ note_id: 'compiled-extends',
+ },
+ ejs: true,
+ jsx: { val: false, note_id: 'compiled-extends' },
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'extends null',
+ exec() {
+ /*
+ class C extends null {
+ constructor() { return Object.create(null); }
+ }
+ return Function.prototype.isPrototypeOf(C)
+ && Object.getPrototypeOf(C.prototype) === null;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ typescript1corejs2: true,
+ tr: true,
+ es6tr: true,
+ jsx: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'new.target',
+ exec() {
+ /*
+ var passed = false;
+ new function f() {
+ passed = new.target === f;
+ }();
+
+ class A {
+ constructor() {
+ passed &= new.target === B;
+ }
+ }
+ class B extends A {}
+ new B();
+ return passed;
+ */
+ },
+ res: {
+ safari10: true,
+ chrome46: 'strict',
+ chrome49: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node5: 'strict',
+ xs6: true,
+ ejs: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'super',
+ category: 'functions',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-super-keyword',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/super',
+ subtests: [
+ {
+ name: 'statement in constructors',
+ exec() {
+ /*
+ var passed = false;
+ class B {
+ constructor(a) { passed = (a === "barbaz"); }
+ }
+ class C extends B {
+ constructor(a) { super("bar" + a); }
+ }
+ new C("baz");
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: false,
+ jsx: true,
+ typescript1corejs2: true,
+ closure: true,
+ es6tr: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'expression in constructors',
+ exec() {
+ /*
+ class B {
+ constructor(a) { return ["foo" + a]; }
+ }
+ class C extends B {
+ constructor(a) { return super("bar" + a); }
+ }
+ return new C("baz")[0] === "foobarbaz";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: false,
+ jsx: true,
+ typescript1corejs2: true,
+ closure: true,
+ es6tr: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari10: true,
+ safari9: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'in methods, property access',
+ exec() {
+ /*
+ class B {}
+ B.prototype.qux = "foo";
+ B.prototype.corge = "baz";
+ class C extends B {
+ quux(a) { return super.qux + a + super["corge"]; }
+ }
+ C.prototype.qux = "garply";
+ return new C().quux("bar") === "foobarbaz";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ jsx: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'in methods, method calls',
+ exec() {
+ /*
+ class B {
+ qux(a) { return "foo" + a; }
+ }
+ class C extends B {
+ qux(a) { return super.qux("bar" + a); }
+ }
+ return new C().qux("baz") === "foobarbaz";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ jsx: true,
+ typescript1corejs2: true,
+ closure: true,
+ es6tr: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'method calls use correct "this" binding',
+ exec() {
+ /*
+ class B {
+ qux(a) { return this.foo + a; }
+ }
+ class C extends B {
+ qux(a) { return super.qux("bar" + a); }
+ }
+ var obj = new C();
+ obj.foo = "foo";
+ return obj.qux("baz") === "foobarbaz";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ jsx: true,
+ typescript1corejs2: true,
+ closure: true,
+ es6tr: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'constructor calls use correct "new.target" binding',
+ exec() {
+ /*
+ var passed;
+ class B {
+ constructor() { passed = (new.target === C); }
+ }
+ class C extends B {
+ constructor() { super(); }
+ }
+ new C();
+ return passed;
+ */
+ },
+ res: {
+ safari10: true,
+ chrome46: 'strict',
+ chrome49: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node5: 'strict',
+ xs6: true,
+ ejs: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'is statically bound',
+ exec() {
+ /*
+ class B {
+ qux() { return "bar"; }
+ }
+ class C extends B {
+ qux() { return super.qux() + this.corge; }
+ }
+ var obj = {
+ qux: C.prototype.qux,
+ corge: "ley"
+ };
+ return obj.qux() === "barley";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure20180506: true,
+ jsx: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'super() invokes the correct constructor',
+ exec() {
+ /*
+ // checks that super() is *not* a synonym of super.constructor()
+ var passed;
+ class B {
+ constructor() {
+ passed = true;
+ }
+ };
+ B.prototype.constructor = function () {
+ passed = false;
+ };
+ class C extends B { };
+ new C;
+ return passed;
+ */
+ },
+ res: {
+ closure: true,
+ node4: 'strict',
+ chrome41: 'strict',
+ chrome49: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ tr: true,
+ ejs: true,
+ jsx: true,
+ es6tr: true,
+ typescript1corejs2: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'object literal extensions',
+ category: 'syntax',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-object-initialiser',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Object_initializer#New_notations_in_ECMAScript_2015',
+ subtests: [
+ {
+ name: 'computed properties',
+ exec() {
+ /*
+ var x = 'y';
+ return ({ [x]: 1 }).y === 1;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ jsx: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ safari7_1: true,
+ opera10_50: false,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'shorthand properties',
+ exec() {
+ /*
+ var a = 7, b = 8, c = {a,b};
+ return c.a === 7 && c.b === 8;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox33: true,
+ opera10_50: false,
+ chrome41: chrome.experimental,
+ chrome43: true,
+ node4: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'shorthand methods',
+ exec() {
+ /*
+ return ({ y() { return 2; } }).y() === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: {
+ val: true,
+ note_id: 'ff-shorthand-methods',
+ note_html:
+ 'Firefox incorrectly produces an error in strict mode if the method is named "arguments"
, "eval"
, or "delete"
.',
+ },
+ opera10_50: false,
+ chrome41: chrome.experimental,
+ chrome43: true,
+ node4: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'string-keyed shorthand methods',
+ exec() {
+ /*
+ return ({ "foo bar"() { return 4; } })["foo bar"]() === 4;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome41: chrome.experimental,
+ chrome43: true,
+ node4: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'computed shorthand methods',
+ exec() {
+ /*
+ var x = 'y';
+ return ({ [x](){ return 1 } }).y() === 1;
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ tr: true,
+ closure: true,
+ babel6corejs2: true,
+ ejs: true,
+ typescript1corejs2: true,
+ jsx: true,
+ es6tr: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ safari9: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed accessors',
+ exec() {
+ /*
+ var x = 'y',
+ valueSet,
+ obj = {
+ get [x] () { return 1 },
+ set [x] (value) { valueSet = value }
+ };
+ obj.y = 'foo';
+ return obj.y === 1 && valueSet === 'foo';
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ tr: true,
+ es6tr: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome44: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'non-strict function semantics',
+ note_id: 'hoisted-block-functions',
+ note_html:
+ 'The 2015 version of the specification contains multiple bugs for hoisted block-level function declaration semantics, which these tests disregard.',
+ category: 'annex b',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-labelled-function-declarations',
+ subtests: [
+ {
+ name: 'hoisted block-level function declaration',
+ exec() {
+ /*
+ // Note: only available outside of strict mode.
+ if (!this) return false;
+ var passed = f() === 1;
+ function f() { return 1; }
+
+ passed &= typeof g === 'undefined';
+ { function g() { return 1; } }
+ passed &= g() === 1;
+
+ passed &= h() === 2;
+ { function h() { return 1; } }
+ function h() { return 2; }
+ passed &= h() === 1;
+
+ return passed;
+ */
+ },
+ res: {
+ ie11: true,
+ firefox2: false,
+ firefox3_5: true,
+ rhino1_7_13: true,
+ chrome49: true,
+ jxa: true,
+ safari10: true,
+ opera10_50: false,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ {
+ name: 'labeled function statements',
+ exec() {
+ /*
+ // Note: only available outside of strict mode.
+ if (!this) return false;
+
+ label: function foo() { return 2; }
+ return foo() === 2;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari4: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ {
+ name: 'function statements in if-statement clauses',
+ exec() {
+ /*
+ // Note: only available outside of strict mode.
+ if (!this) return false;
+
+ if(true) function foo() { return 2; }
+ if(false) {} else function bar() { return 3; }
+ if(true) function baz() { return 4; } else {}
+ if(false) function qux() { return 5; } else function qux() { return 6; }
+ return foo() === 2 && bar() === 3 && baz() === 4 && qux() === 6;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari4: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ ],
+ },
+ {
+ name: '__proto__ in object literals',
+ category: 'annex b',
+ significance: 'tiny',
+ note_id: 'proto-in-object-literals',
+ note_html:
+ 'Note that this is distinct from the existence or functionality of Object.prototype.__proto__
.',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-__proto__-property-names-in-object-initializers',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto#Specifications',
+ subtests: [
+ {
+ name: 'basic support',
+ exec() {
+ /*
+ return { __proto__ : [] } instanceof Array
+ && !({ __proto__ : null } instanceof Object);
+ */
+ },
+ res: {
+ ie11: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: false,
+ opera12_10: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'multiple __proto__ is an error',
+ exec() {
+ /*
+ try {
+ eval("({ __proto__ : [], __proto__: {} })");
+ }
+ catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome42: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'not a computed property',
+ exec() {
+ /*
+ if (!({ __proto__ : [] } instanceof Array)) {
+ return false;
+ }
+ var a = "__proto__";
+ return !({ [a] : [] } instanceof Array);
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'not a shorthand property',
+ exec() {
+ /*
+ if (!({ __proto__ : [] } instanceof Array)) {
+ return false;
+ }
+ var __proto__ = [];
+ return !({ __proto__ } instanceof Array);
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome42: true,
+ node4: true,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'not a shorthand method',
+ exec() {
+ /*
+ if (!({ __proto__ : [] } instanceof Array)) {
+ return false;
+ }
+ return !({ __proto__(){} } instanceof Function);
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome42: true,
+ node4: true,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'for..of loops',
+ category: 'syntax',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-for-in-and-for-of-statements',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of',
+ subtests: [
+ {
+ name: 'with arrays',
+ exec() {
+ /*
+ var arr = [5];
+ for (var item of arr)
+ return item === 5;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ jsx: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with sparse arrays',
+ exec() {
+ /*
+ var arr = [,,];
+ var count = 0;
+ for (var item of arr)
+ count += (item === void undefined);
+ return count === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ jsx: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with strings',
+ exec() {
+ /*
+ var str = "";
+ for (var item of "foo")
+ str += item;
+ return str === "foo";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox17: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with astral plane strings',
+ exec() {
+ /*
+ var str = "";
+ for (var item of "𠮷𠮶")
+ str += item + " ";
+ return str === "𠮷 𠮶 ";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with generator instances',
+ exec() {
+ /*
+ var result = "";
+ var iterable = (function*(){ yield 1; yield 2; yield 3; }());
+ for (var item of iterable) {
+ result += item;
+ }
+ return result === "123";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with generic iterables',
+ exec() {
+ /*
+ var result = "";
+ var iterable = global.__createIterableObject([1, 2, 3]);
+ for (var item of iterable) {
+ result += item;
+ }
+ return result === "123";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ es6tr: { val: true, note_id: 'compiler-iterable' },
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'with instances of generic iterables',
+ exec() {
+ /*
+ var result = "";
+ var iterable = global.__createIterableObject([1, 2, 3]);
+ for (var item of Object.create(iterable)) {
+ result += item;
+ }
+ return result === "123";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ es6tr: { val: true, note_id: 'compiler-iterable' },
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome35: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'iterator closing, break',
+ exec() {
+ /*
+ var closed = false;
+ var iter = __createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ for (var it of iter) break;
+ return closed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ safari9: true,
+ xs6: true,
+ chrome51: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'iterator closing, throw',
+ exec() {
+ /*
+ var closed = false;
+ var iter = __createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ try {
+ for (var it of iter) throw 0;
+ } catch(e){}
+ return closed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ safari9: true,
+ xs6: true,
+ chrome51: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'generators',
+ category: 'functions',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-generator-function-definitions',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ function * generator(){
+ yield 5; yield 6;
+ };
+ var iterator = generator();
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'generator function expressions',
+ exec() {
+ /*
+ var generator = function * (){
+ yield 5; yield 6;
+ };
+ var iterator = generator();
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'correct "this" binding',
+ exec() {
+ /*
+ function * generator(){
+ yield this.x; yield this.y;
+ };
+ var iterator = { g: generator, x: 5, y: 6 }.g();
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ closure20180319: false,
+ closure20180506: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'can\'t use "this" with new',
+ exec() {
+ /*
+ function * generator(){
+ yield this.x; yield this.y;
+ };
+ try {
+ (new generator()).next();
+ }
+ catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox43: true,
+ opera10_50: false,
+ chrome50: true,
+ node6: true,
+ node6_5: true,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'sending',
+ exec() {
+ /*
+ var sent;
+ function * generator(){
+ sent = [yield 5, yield 6];
+ };
+ var iterator = generator();
+ iterator.next();
+ iterator.next("foo");
+ iterator.next("bar");
+ return sent[0] === "foo" && sent[1] === "bar";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ ejs: true,
+ closure: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '%GeneratorPrototype%',
+ exec() {
+ /*
+ function * generatorFn(){}
+ var ownProto = Object.getPrototypeOf(generatorFn());
+ var passed = ownProto === generatorFn.prototype;
+
+ var sharedProto = Object.getPrototypeOf(ownProto);
+ passed &= sharedProto !== Object.prototype &&
+ sharedProto === Object.getPrototypeOf(function*(){}.prototype) &&
+ sharedProto.hasOwnProperty('next');
+
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '%GeneratorPrototype% prototype chain',
+ exec() {
+ /*
+ function * generatorFn(){}
+ var g = generatorFn();
+ var ownProto = Object.getPrototypeOf(g);
+ var passed = ownProto === generatorFn.prototype;
+
+ var sharedProto = Object.getPrototypeOf(ownProto);
+ var iterProto = Object.getPrototypeOf(sharedProto);
+
+ passed &= iterProto.hasOwnProperty(Symbol.iterator) &&
+ !sharedProto .hasOwnProperty(Symbol.iterator) &&
+ !ownProto .hasOwnProperty(Symbol.iterator) &&
+ g[Symbol.iterator]() === g;
+
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome45: true,
+ node0_12: 'flagged',
+ node4: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '%GeneratorPrototype%.constructor',
+ exec() {
+ /*
+ function * g (){}
+ var iterator = new g.constructor("a","b","c","yield a; yield b; yield c;")(5,6,7);
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 7 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+
+ passed &= g.constructor === (function*(){}).constructor;
+ return passed;
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '%GeneratorPrototype%.throw',
+ exec() {
+ /*
+ var passed = false;
+ function * generator(){
+ try {
+ yield 5; yield 6;
+ } catch(e) {
+ passed = (e === "foo");
+ }
+ };
+ var iterator = generator();
+ iterator.next();
+ iterator.throw("foo");
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '%GeneratorPrototype%.return',
+ exec() {
+ /*
+ function * generator(){
+ yield 5; yield 6;
+ };
+ var iterator = generator();
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.return("quxquux");
+ passed &= item.value === "quxquux" && item.done === true;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure20180319: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ chrome50: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'yield operator precedence',
+ exec() {
+ /*
+ var passed;
+ function * generator(){
+ passed = yield 0 ? true : false;
+ };
+ var iterator = generator();
+ iterator.next();
+ iterator.next(true);
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'yield *, arrays',
+ exec() {
+ /*
+ var iterator = (function * generator() {
+ yield * [5, 6];
+ }());
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome38: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'yield *, sparse arrays',
+ exec() {
+ /*
+ var iterator = (function * generator() {
+ yield * [,,];
+ }());
+ var item = iterator.next();
+ var passed = item.value === void undefined && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome38: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'yield *, strings',
+ exec() {
+ /*
+ var iterator = (function * generator() {
+ yield * "56";
+ }());
+ var item = iterator.next();
+ var passed = item.value === "5" && item.done === false;
+ item = iterator.next();
+ passed &= item.value === "6" && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ tr: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome38: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'yield *, astral plane strings',
+ exec() {
+ /*
+ var iterator = (function * generator() {
+ yield * "𠮷𠮶";
+ }());
+ var item = iterator.next();
+ var passed = item.value === "𠮷" && item.done === false;
+ item = iterator.next();
+ passed &= item.value === "𠮶" && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ ejs: true,
+ tr: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome38: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'yield *, generator instances',
+ exec() {
+ /*
+ var iterator = (function * generator() {
+ yield * (function*(){ yield 5; yield 6; yield 7; }());
+ }());
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 7 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ ejs: true,
+ closure: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'yield *, generic iterables',
+ exec() {
+ /*
+ var iterator = (function * generator() {
+ yield * global.__createIterableObject([5, 6, 7]);
+ }());
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 7 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ ejs: true,
+ closure: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'yield *, instances of iterables',
+ exec() {
+ /*
+ var iterator = (function * generator() {
+ yield * Object.create(__createIterableObject([5, 6, 7]));
+ }());
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 7 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome35: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'yield * on non-iterables is a runtime error',
+ exec() {
+ /*
+ var iterator = (function * generator() {
+ yield * [5];
+ }());
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ iterator = (function * generator() {
+ yield * 5;
+ }());
+ try {
+ iterator.next();
+ } catch (e) {
+ return passed;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: false,
+ typescript1corejs2: false,
+ closure20230228: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ chrome35: chrome.experimental,
+ chrome39: true,
+ node0_12: 'flagged',
+ node4: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'yield *, iterator closing',
+ exec() {
+ /*
+ var closed = '';
+ var iter = __createIterableObject([1, 2, 3], {
+ 'return': function(){
+ closed += 'a';
+ return {done: true};
+ }
+ });
+ var gen = (function* generator(){
+ try {
+ yield *iter;
+ } finally {
+ closed += 'b';
+ }
+ })();
+ gen.next();
+ gen['return']();
+ return closed === 'ab';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure20180319: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome50: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'yield *, iterator closing via throw()',
+ exec() {
+ /*
+ var closed = false;
+ var iter = global.__createIterableObject([1, 2, 3], {
+ 'throw': undefined,
+ 'return': function() {
+ closed = true;
+ return {done: true};
+ }
+ });
+ var gen = (function*(){
+ try {
+ yield *iter;
+ } catch(e){}
+ })();
+ gen.next();
+ gen['throw']();
+ return closed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome50: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'shorthand generator methods',
+ exec() {
+ /*
+ var o = {
+ * generator() {
+ yield 5; yield 6;
+ }
+ };
+ var iterator = o.generator();
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ chrome41: chrome.experimental,
+ chrome42: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'string-keyed shorthand generator methods',
+ exec() {
+ /*
+ var o = {
+ * "foo bar"() {
+ yield 5; yield 6;
+ }
+ };
+ var iterator = o["foo bar"]();
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ chrome41: chrome.experimental,
+ chrome42: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ node4: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed shorthand generators',
+ exec() {
+ /*
+ var garply = "generator";
+ var o = {
+ * [garply] () {
+ yield 5; yield 6;
+ }
+ };
+ var iterator = o.generator();
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ ejs: true,
+ chrome44: true,
+ ie11: false,
+ edge12: edge.experimental,
+ node4: true,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'shorthand generator methods, classes',
+ exec() {
+ /*
+ class C {
+ * generator() {
+ yield 5; yield 6;
+ }
+ };
+ var iterator = new C().generator();
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'computed shorthand generators, classes',
+ exec() {
+ /*
+ var garply = "generator";
+ class C {
+ * [garply] () {
+ yield 5; yield 6;
+ }
+ }
+ var iterator = new C().generator();
+ var item = iterator.next();
+ var passed = item.value === 5 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === 6 && item.done === false;
+ item = iterator.next();
+ passed &= item.value === void undefined && item.done === true;
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ closure: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ chrome45: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: "shorthand generators can't be constructors",
+ exec() {
+ /*
+ class C {
+ * generator() {
+ yield 5; yield 6;
+ }
+ };
+ try {
+ Function("class D { * constructor() { return {}; } }");
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.regenerator,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome41: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'prototype of bound functions',
+ category: 'misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-boundfunctioncreate',
+ subtests: [
+ {
+ name: 'basic functions',
+ exec() {
+ /*
+ function correctProtoBound(proto) {
+ var f = function(){};
+ if (Object.setPrototypeOf) {
+ Object.setPrototypeOf(f, proto);
+ } else {
+ f.__proto__ = proto;
+ }
+ var boundF = Function.prototype.bind.call(f, null);
+ return Object.getPrototypeOf(boundF) === proto;
+ }
+ return correctProtoBound(Function.prototype)
+ && correctProtoBound({})
+ && correctProtoBound(null);
+ */
+ },
+ res: {
+ chrome46: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node5: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ jxa: true,
+ duktape1_0: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'generator functions',
+ exec() {
+ /*
+ function correctProtoBound(proto) {
+ var f = function*(){};
+ if (Object.setPrototypeOf) {
+ Object.setPrototypeOf(f, proto);
+ } else {
+ f.__proto__ = proto;
+ }
+ var boundF = Function.prototype.bind.call(f, null);
+ return Object.getPrototypeOf(boundF) === proto;
+ }
+ return correctProtoBound(Function.prototype)
+ && correctProtoBound({})
+ && correctProtoBound(null);
+ */
+ },
+ res: {
+ chrome46: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node5: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'arrow functions',
+ exec() {
+ /*
+ function correctProtoBound(proto) {
+ var f = ()=>5;
+ if (Object.setPrototypeOf) {
+ Object.setPrototypeOf(f, proto);
+ } else {
+ f.__proto__ = proto;
+ }
+ var boundF = Function.prototype.bind.call(f, null);
+ return Object.getPrototypeOf(boundF) === proto;
+ }
+ return correctProtoBound(Function.prototype)
+ && correctProtoBound({})
+ && correctProtoBound(null);
+ */
+ },
+ res: {
+ chrome46: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node5: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'classes',
+ exec() {
+ /*
+ function correctProtoBound(proto) {
+ class C {}
+ if (Object.setPrototypeOf) {
+ Object.setPrototypeOf(C, proto);
+ } else {
+ C.__proto__ = proto;
+ }
+ var boundF = Function.prototype.bind.call(C, null);
+ return Object.getPrototypeOf(boundF) === proto;
+ }
+ return correctProtoBound(Function.prototype)
+ && correctProtoBound({})
+ && correctProtoBound(null);
+ */
+ },
+ res: {
+ chrome46: 'strict',
+ chrome49: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node5: 'strict',
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'subclasses',
+ exec() {
+ /*
+ function correctProtoBound(superclass) {
+ class C extends superclass {
+ constructor() {
+ return Object.create(null);
+ }
+ }
+ var boundF = Function.prototype.bind.call(C, null);
+ return Object.getPrototypeOf(boundF) === Object.getPrototypeOf(C);
+ }
+ return correctProtoBound(function(){})
+ && correctProtoBound(Array)
+ && correctProtoBound(null);
+ */
+ },
+ res: {
+ chrome46: 'strict',
+ chrome49: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node5: 'strict',
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'octal and binary literals',
+ category: 'syntax',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-literals-numeric-literals',
+ subtests: [
+ {
+ name: 'octal literals',
+ exec() {
+ /*
+ return 0o10 === 8 && 0O10 === 8;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'binary literals',
+ exec() {
+ /*
+ return 0b10 === 2 && 0B10 === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'octal supported by Number()',
+ exec() {
+ /*
+ return Number('0o1') === 1;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'binary supported by Number()',
+ exec() {
+ /*
+ return Number('0b1') === 1;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'template literals',
+ category: 'syntax',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-template-literals',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ var a = "ba", b = "QUX";
+ return `foo bar
+ ${a + "z"} ${b.toLowerCase()}` === "foo bar\nbaz qux";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome41: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'toString conversion',
+ exec() {
+ /*
+ var a = {
+ toString: function() { return "foo"; },
+ valueOf: function() { return "bar"; }
+ };
+ return `${a}` === "foo";
+ */
+ },
+ res: {
+ ejs: true,
+ closure: false,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome41: true,
+ safari9: true,
+ node4: true,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'tagged template literals',
+ exec() {
+ /*
+ var called = false;
+ function fn(parts, a, b) {
+ called = true;
+ return parts instanceof Array &&
+ parts[0] === "foo" &&
+ parts[1] === "bar\n" &&
+ parts.raw[0] === "foo" &&
+ parts.raw[1] === "bar\\n" &&
+ a === 123 &&
+ b === 456;
+ }
+ return fn `foo${123}bar\n${456}` && called;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ closure20200315: false,
+ closure20200517: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome41: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'passed array is frozen',
+ exec() {
+ /*
+ return (function(parts) {
+ return Object.isFrozen(parts) && Object.isFrozen(parts.raw);
+ }) `foo${0}bar${0}baz`;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: true,
+ closure: false,
+ es6tr: true,
+ jsx: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome41: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'line break normalisation',
+ /* For some reason, this .fromCharCode stuff is necessary instead of \r\n. */
+ exec() {
+ /*
+ var cr = eval("`x" + String.fromCharCode(13) + "y`");
+ var lf = eval("`x" + String.fromCharCode(10) + "y`");
+ var crlf = eval("`x" + String.fromCharCode(13,10) + "y`");
+
+ return cr.length === 3 && lf.length === 3 && crlf.length === 3
+ && cr[1] === lf[1] && lf[1] === crlf[1] && crlf[1] === '\n';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ chrome41: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'TemplateStrings call site caching',
+ exec() {
+ /*
+ // TemplateStrings caching was changed from per-contents to
+ // per-call-site.
+ // https://github.com/tc39/ecma262/pull/890
+ function strings(array) {
+ return array;
+ }
+ function getStrings() {
+ return strings`foo`;
+ }
+ var original = getStrings();
+ var other = strings`foo`;
+ return original === getStrings() && original !== other;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ closure20200315: false,
+ closure20200517: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome41: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'TemplateStrings permanent caching',
+ exec() {
+ /*
+ function strings(array) {
+ return array;
+ }
+ function getStrings() {
+ return strings`foo`;
+ }
+ var original = getStrings();
+ var newed = new getStrings();
+ return original === getStrings() && original === newed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ closure20200315: false,
+ closure20200517: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome41: true,
+ safari9: true,
+ safari12: safari.templateStringsPermanentCaching,
+ safari13: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'RegExp "y" and "u" flags',
+ category: 'syntax',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-get-regexp.prototype.sticky',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp#Parameters',
+ subtests: [
+ {
+ name: '"y" flag',
+ exec() {
+ /*
+ var re = new RegExp('\\w', 'y');
+ re.exec('xy');
+ return (re.exec('xy')[0] === 'y');
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ chrome39: chrome.experimental,
+ chrome40: false,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: '"y" flag, lastIndex',
+ exec() {
+ /*
+ var re = new RegExp('yy', 'y');
+ re.lastIndex = 3;
+ var result = re.exec('xxxyyxx')[0];
+ return result === 'yy' && re.lastIndex === 5;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ chrome39: chrome.experimental,
+ chrome40: false,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: '"u" flag',
+ exec() {
+ /*
+ return "𠮷".match(/^.$/u)[0].length === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ edge13: true,
+ firefox2: false,
+ firefox46: true,
+ opera10_50: false,
+ chrome50: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"u" flag, non-BMP Unicode characters',
+ exec() {
+ /*
+ return "𠮷x".match(/^.x$/u)[0].length === 3;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ edge13: true,
+ firefox2: false,
+ firefox46: true,
+ opera10_50: false,
+ chrome50: true,
+ node6: true,
+ node6_5: true,
+ safari10: null,
+ safari12: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"u" flag, Unicode code point escapes',
+ exec() {
+ /*
+ return "𝌆".match(/\u{1d306}/u)[0].length === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ edge13: true,
+ firefox2: false,
+ firefox46: true,
+ opera10_50: false,
+ chrome50: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"u" flag, case folding',
+ exec() {
+ /*
+ return "ſ".match(/S/iu) && "S".match(/ſ/iu);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox46: true,
+ opera10_50: false,
+ chrome50: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'typed arrays',
+ category: 'built-ins',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-typedarray-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray',
+ subtests: [
+ {
+ name: 'Int8Array',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int8Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new Int8Array(buffer); view[0] = 0x80;
+ return view[0] === -0x80;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Uint8Array',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new Uint8Array(buffer); view[0] = 0x100;
+ return view[0] === 0;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Uint8ClampedArray',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint8ClampedArray',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new Uint8ClampedArray(buffer); view[0] = 0x100;
+ return view[0] === 0xFF;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: {
+ val: true,
+ note_id: 'ie-clampedarray',
+ note_html:
+ "A buggy implementation of Uint8ClampedArray
on initial IE11 release has been fixed with the patch on KB2929437",
+ },
+ edge12: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari6: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Int16Array',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int16Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new Int16Array(buffer); view[0] = 0x8000;
+ return view[0] === -0x8000;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Uint16Array',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint16Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new Uint16Array(buffer); view[0] = 0x10000;
+ return view[0] === 0;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Int32Array',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Int32Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new Int32Array(buffer); view[0] = 0x80000000;
+ return view[0] === -0x80000000;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Uint32Array',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Uint32Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new Uint32Array(buffer); view[0] = 0x100000000;
+ return view[0] === 0;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Float32Array',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new Float32Array(buffer); view[0] = 0.1;
+ return view[0] === 0.10000000149011612;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Float64Array',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float64Array',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new Float64Array(buffer); view[0] = 0.1;
+ return view[0] === 0.1;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: false,
+ android4_1: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'DataView (Int8)',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setInt8 (0, 0x80);
+ return view.getInt8(0) === -0x80;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox15: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'DataView (Uint8)',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setUint8(0, 0x100);
+ return view.getUint8(0) === 0;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox15: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'DataView (Int16)',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setInt16(0, 0x8000);
+ return view.getInt16(0) === -0x8000;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox15: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'DataView (Uint16)',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setUint16(0, 0x10000);
+ return view.getUint16(0) === 0;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox15: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'DataView (Int32)',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setInt32(0, 0x80000000);
+ return view.getInt32(0) === -0x80000000;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox15: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'DataView (Uint32)',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setUint32(0, 0x100000000);
+ return view.getUint32(0) === 0;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox15: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'DataView (Float32)',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setFloat32(0, 0.1);
+ return view.getFloat32(0) === 0.10000000149011612;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox15: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'DataView (Float64)',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/DataView',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var view = new DataView(buffer);
+ view.setFloat64(0, 0.1);
+ return view.getFloat64(0) === 0.1;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie10: true,
+ firefox2: false,
+ firefox15: true,
+ chrome5: true,
+ safari5_1: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape1_3: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'ArrayBuffer[Symbol.species]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer/@@species',
+ exec() {
+ /*
+ return typeof ArrayBuffer[Symbol.species] === 'function';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'constructors require new',
+ exec() {
+ /*
+ var buffer = new ArrayBuffer(64);
+ var constructors = [
+ 'ArrayBuffer',
+ 'DataView',
+ 'Int8Array',
+ 'Uint8Array',
+ 'Uint8ClampedArray',
+ 'Int16Array',
+ 'Uint16Array',
+ 'Int32Array',
+ 'Uint32Array',
+ 'Float32Array',
+ 'Float64Array'
+ ];
+ return constructors.every(function (constructor) {
+ try {
+ if (constructor in global) {
+ global[constructor](constructor === "ArrayBuffer" ? 64 : buffer);
+ }
+ return false;
+ } catch(e) {
+ return true;
+ }
+ });
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ firefox2: false,
+ firefox44: true,
+ opera10_50: false,
+ ie11: false,
+ edge14: true,
+ chrome5: true,
+ safari10: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ ejs: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'constructors accept generic iterables',
+ exec() {
+ /*
+ var constructors = [
+ 'Int8Array',
+ 'Uint8Array',
+ 'Uint8ClampedArray',
+ 'Int16Array',
+ 'Uint16Array',
+ 'Int32Array',
+ 'Uint32Array',
+ 'Float32Array',
+ 'Float64Array'
+ ];
+ for(var i = 0; i < constructors.length; i++){
+ var arr = new global[constructors[i]](__createIterableObject([1, 2, 3]));
+ if(arr.length !== 3 || arr[0] !== 1 || arr[1] !== 2 || arr[2] !== 3)return false;
+ }
+ return true;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ chrome45: true,
+ ie11: false,
+ edge14: true,
+ node4: true,
+ safari10: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'correct prototype chains',
+ exec() {
+ /*
+ var constructors = [
+ 'Int8Array',
+ 'Uint8Array',
+ 'Uint8ClampedArray',
+ 'Int16Array',
+ 'Uint16Array',
+ 'Int32Array',
+ 'Uint32Array',
+ 'Float32Array',
+ 'Float64Array'
+ ];
+ var constructor = Object.getPrototypeOf(Int8Array);
+ var prototype = Object.getPrototypeOf(Int8Array.prototype);
+ if(constructor === Function.prototype || prototype === Object.prototype)return false;
+ for(var i = 0; i < constructors.length; i+=1) {
+ if (!(constructors[i] in global
+ && Object.getPrototypeOf(global[constructors[i]]) === constructor
+ && Object.getPrototypeOf(global[constructors[i]].prototype) === prototype
+ && Object.getOwnPropertyNames(global[constructors[i]].prototype).sort() + ''
+ === "BYTES_PER_ELEMENT,constructor")) {
+ return false;
+ }
+ }
+ return true;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ chrome51: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_1: true,
+ duktape2_5: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ].concat(
+ [
+ // @@ jph
+ {
+ name: '.from',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/from',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.of',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/of',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.subarray',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/subarray',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: {
+ val: true,
+ note_id: 'ie-subarray',
+ note_html:
+ "This test depends on Uint8ClampedArray
which has been introduced with KB2929437, so it fails on early IE11 builds.",
+ },
+ edge12: true,
+ firefox2: false,
+ firefox4: true,
+ chrome5: true,
+ safari6: true,
+ opera10_50: false,
+ opera12: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '.prototype.join',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/join',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.indexOf',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/indexOf',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.lastIndexOf',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/lastIndexOf',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.slice',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/slice',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.every',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/every',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.filter',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/filter',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.forEach',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/forEach',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.map',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/map',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.reduce',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduce',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.reduceRight',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reduceRight',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.reverse',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/reverse',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.some',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/some',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.sort',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/sort',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox46: true,
+ opera10_50: false,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.copyWithin',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/copyWithin',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.find',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/find',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.findIndex',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/findIndex',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.fill',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/fill',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.keys',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/keys',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ chrome38: true,
+ node0_12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.values',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/values',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ chrome38: true,
+ node0_12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ejs: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype.entries',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/entries',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ chrome38: true,
+ node0_12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '.prototype[Symbol.iterator]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/@@iterator',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ chrome38: true,
+ node0_12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ ejs: true,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '[Symbol.species]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/TypedArray/@@species',
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ].map(function (m) {
+ const eqFn = ' === "function"'
+ const name = m.name
+ // TODO: fix this eval
+ // m.name = `%TypedArray%${name}`
+ // m.exec = eval(
+ // `0,function(){/*\nreturn typeof ${[
+ // 'Int8Array',
+ // 'Uint8Array',
+ // 'Uint8ClampedArray',
+ // 'Int16Array',
+ // 'Uint16Array',
+ // 'Int32Array',
+ // 'Uint32Array',
+ // 'Float32Array',
+ // 'Float64Array',
+ // ].join(`${name + eqFn} &&\n typeof `)}${name}${eqFn};\n*/}`
+ // )
+ return {
+ name: `%TypedArray%${name}`,
+ category: m.category,
+ exec() {
+ return false
+ },
+ res: m.res,
+ }
+ })
+ ),
+ },
+ {
+ name: 'Map',
+ category: 'built-ins',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-map-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ var key = {};
+ var map = new Map();
+
+ map.set(key, 123);
+
+ return map.has(key) && map.get(key) === 123;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor arguments',
+ exec() {
+ /*
+ var key1 = {};
+ var key2 = {};
+ var map = new Map([[key1, 123], [key2, 456]]);
+
+ return map.has(key1) && map.get(key1) === 123 &&
+ map.has(key2) && map.get(key2) === 456;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor requires new',
+ exec() {
+ /*
+ new Map();
+ try {
+ Map();
+ return false;
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: true,
+ chrome38: true,
+ safari9: true,
+ node4: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor accepts null',
+ exec() {
+ /*
+ new Map(null);
+ return true;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox10: false,
+ firefox17: false,
+ firefox37: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor invokes set',
+ exec() {
+ /*
+ var passed = false;
+ var _set = Map.prototype.set;
+
+ Map.prototype.set = function(k, v) {
+ passed = true;
+ };
+
+ new Map([ [1, 2] ]);
+ Map.prototype.set = _set;
+
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'iterator closing',
+ exec() {
+ /*
+ var closed = false;
+ var iter = global.__createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ try {
+ new Map(iter);
+ } catch(e){}
+ return closed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome51: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Map.prototype.set returns this',
+ exec() {
+ /*
+ var map = new Map();
+ return map.set(0, 0) === map;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox33: true,
+ opera10_50: false,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '-0 key converts to +0',
+ exec() {
+ /*
+ var map = new Map();
+ map.set(-0, "foo");
+ var k;
+ map.forEach(function (value, key) {
+ k = 1 / key;
+ });
+ return k === Infinity && map.get(+0) === "foo";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure20180506: true,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ opera10_50: false,
+ chrome39: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Map.prototype.size',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/size',
+ exec() {
+ /*
+ var key = {};
+ var map = new Map();
+
+ map.set(key, 123);
+
+ return map.size === 1;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox19: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Map.prototype.delete',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/delete',
+ exec() {
+ /*
+ return typeof Map.prototype.delete === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Map.prototype.clear',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/clear',
+ exec() {
+ /*
+ return typeof Map.prototype.clear === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox19: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Map.prototype.forEach',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/forEach',
+ exec() {
+ /*
+ return typeof Map.prototype.forEach === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome36: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Map.prototype.keys',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/keys',
+ exec() {
+ /*
+ return typeof Map.prototype.keys === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox20: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome37: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Map.prototype.values',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/values',
+ exec() {
+ /*
+ return typeof Map.prototype.values === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox20: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome36: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Map.prototype.entries',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/entries',
+ exec() {
+ /*
+ return typeof Map.prototype.entries === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox20: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome36: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Map.prototype[Symbol.iterator]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@iterator',
+ exec() {
+ /*
+ return typeof Map.prototype[Symbol.iterator] === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome37: chrome.experimental,
+ chrome38: true,
+ safari9: true,
+ ie11: false,
+ edge12: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: "Map.prototype isn't an instance",
+ exec() {
+ /*
+ new Map();
+ var obj = {};
+ try {
+ Map.prototype.has(obj);
+ }
+ catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Map iterator prototype chain',
+ exec() {
+ /*
+ // Iterator instance
+ var iterator = new Map()[Symbol.iterator]();
+ // %MapIteratorPrototype%
+ var proto1 = Object.getPrototypeOf(iterator);
+ // %IteratorPrototype%
+ var proto2 = Object.getPrototypeOf(proto1);
+
+ return proto2.hasOwnProperty(Symbol.iterator) &&
+ !proto1 .hasOwnProperty(Symbol.iterator) &&
+ !iterator .hasOwnProperty(Symbol.iterator) &&
+ iterator[Symbol.iterator]() === iterator;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Map[Symbol.species]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map/@@species',
+ exec() {
+ /*
+ var prop = Object.getOwnPropertyDescriptor(Map, Symbol.species);
+ return 'get' in prop && Map[Symbol.species] === Map;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ firefox2: false,
+ firefox41: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Set',
+ category: 'built-ins',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-set-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ var obj = {};
+ var set = new Set();
+
+ set.add(123);
+ set.add(123);
+
+ return set.has(123);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor arguments',
+ exec() {
+ /*
+ var obj1 = {};
+ var obj2 = {};
+ var set = new Set([obj1, obj2]);
+
+ return set.has(obj1) && set.has(obj2);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor requires new',
+ exec() {
+ /*
+ new Set();
+ try {
+ Set();
+ return false;
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: true,
+ chrome38: true,
+ safari9: true,
+ node4: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor accepts null',
+ exec() {
+ /*
+ new Set(null);
+ return true;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor invokes add',
+ exec() {
+ /*
+ var passed = false;
+ var _add = Set.prototype.add;
+
+ Set.prototype.add = function(v) {
+ passed = true;
+ };
+
+ new Set([1]);
+ Set.prototype.add = _add;
+
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'iterator closing',
+ exec() {
+ /*
+ var closed = false;
+ var iter = global.__createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ var add = Set.prototype.add;
+ Set.prototype.add = function(){ throw 0 };
+ try {
+ new Set(iter);
+ } catch(e){}
+ Set.prototype.add = add;
+ return closed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome51: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Set.prototype.add returns this',
+ exec() {
+ /*
+ var set = new Set();
+ return set.add(0) === set;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox33: true,
+ opera10_50: false,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '-0 key converts to +0',
+ exec() {
+ /*
+ var set = new Set();
+ set.add(-0);
+ var k;
+ set.forEach(function (value) {
+ k = 1 / value;
+ });
+ return k === Infinity && set.has(+0);
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure20180506: true,
+ es6shim: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ opera10_50: false,
+ chrome39: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ ejs: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Set.prototype.size',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/size',
+ exec() {
+ /*
+ var obj = {};
+ var set = new Set();
+
+ set.add(123);
+ set.add(123);
+ set.add(456);
+
+ return set.size === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox19: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Set.prototype.delete',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/delete',
+ exec() {
+ /*
+ return typeof Set.prototype.delete === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Set.prototype.clear',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/clear',
+ exec() {
+ /*
+ return typeof Set.prototype.clear === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox19: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Set.prototype.forEach',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/forEach',
+ exec() {
+ /*
+ return typeof Set.prototype.forEach === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome36: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Set.prototype.keys',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/keys',
+ exec() {
+ /*
+ return typeof Set.prototype.keys === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox24: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Set.prototype.values',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/values',
+ exec() {
+ /*
+ return typeof Set.prototype.values === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox24: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome37: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Set.prototype.entries',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/entries',
+ exec() {
+ /*
+ return typeof Set.prototype.entries === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox24: true,
+ opera10_50: false,
+ safari7_1: true,
+ chrome37: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Set.prototype[Symbol.iterator]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@iterator',
+ exec() {
+ /*
+ return typeof Set.prototype[Symbol.iterator] === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ chrome51: true,
+ ejs: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome37: chrome.experimental,
+ chrome38: true,
+ safari9: true,
+ ie11: false,
+ edge12: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: "Set.prototype isn't an instance",
+ exec() {
+ /*
+ new Set();
+ var obj = {};
+ try {
+ Set.prototype.has(obj);
+ }
+ catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Set iterator prototype chain',
+ exec() {
+ /*
+ // Iterator instance
+ var iterator = new Set()[Symbol.iterator]();
+ // %SetIteratorPrototype%
+ var proto1 = Object.getPrototypeOf(iterator);
+ // %IteratorPrototype%
+ var proto2 = Object.getPrototypeOf(proto1);
+
+ return proto2.hasOwnProperty(Symbol.iterator) &&
+ !proto1 .hasOwnProperty(Symbol.iterator) &&
+ !iterator .hasOwnProperty(Symbol.iterator) &&
+ iterator[Symbol.iterator]() === iterator;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Set[Symbol.species]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Set/@@species',
+ exec() {
+ /*
+ var prop = Object.getOwnPropertyDescriptor(Set, Symbol.species);
+ return 'get' in prop && Set[Symbol.species] === Set;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ firefox2: false,
+ firefox41: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'WeakMap',
+ category: 'built-ins',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-weakmap-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ var key = {};
+ var weakmap = new WeakMap();
+
+ weakmap.set(key, 123);
+
+ return weakmap.has(key) && weakmap.get(key) === 123;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox6: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome36: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor arguments',
+ exec() {
+ /*
+ var key1 = {};
+ var key2 = {};
+ var weakmap = new WeakMap([[key1, 123], [key2, 456]]);
+
+ return weakmap.has(key1) && weakmap.get(key1) === 123 &&
+ weakmap.has(key2) && weakmap.get(key2) === 456;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor requires new',
+ exec() {
+ /*
+ new WeakMap();
+ try {
+ WeakMap();
+ return false;
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ chrome36: true,
+ safari7_1: true,
+ node4: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor accepts null',
+ exec() {
+ /*
+ new WeakMap(null);
+ return true;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox10: true,
+ firefox17: true,
+ firefox37: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome36: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor invokes set',
+ exec() {
+ /*
+ var passed = false;
+ var _set = WeakMap.prototype.set;
+
+ WeakMap.prototype.set = function(k, v) {
+ passed = true;
+ };
+
+ new WeakMap([ [{ }, 42] ]);
+ WeakMap.prototype.set = _set;
+
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'frozen objects as keys',
+ exec() {
+ /*
+ var f = Object.freeze({});
+ var m = new WeakMap;
+ m.set(f, 42);
+ return m.get(f) === 42;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox6: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome36: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'iterator closing',
+ exec() {
+ /*
+ var closed = false;
+ var iter = global.__createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ try {
+ new WeakMap(iter);
+ } catch(e){}
+ return closed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome51: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'WeakMap.prototype.set returns this',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/set#Return_value',
+ exec() {
+ /*
+ var weakmap = new WeakMap();
+ var key = {};
+ return weakmap.set(key, 0) === weakmap;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ chrome38: true,
+ firefox2: false,
+ firefox33: true,
+ opera10_50: false,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'WeakMap.prototype.delete',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/delete',
+ exec() {
+ /*
+ return typeof WeakMap.prototype.delete === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox6: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome36: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'no WeakMap.prototype.clear method',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap/clear',
+ exec() {
+ /*
+ if (!("clear" in WeakMap.prototype)) {
+ return true;
+ }
+ var m = new WeakMap();
+ var key = {};
+ m.set(key, 2);
+ m.clear();
+ return m.has(key);
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ chrome43: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox6: true,
+ firefox20: false,
+ firefox46: true,
+ opera10_50: false,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '.has, .get and .delete methods accept primitives',
+ exec() {
+ /*
+ var m = new WeakMap;
+ return m.has(1) === false
+ && m.get(1) === void undefined
+ && m.delete(1) === false;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ chrome41: true,
+ safari9: true,
+ ejs: null,
+ xs6: null,
+ jxa: null,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: "WeakMap.prototype isn't an instance",
+ exec() {
+ /*
+ new WeakMap();
+ var obj = {};
+ try {
+ WeakMap.prototype.has(obj);
+ }
+ catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: true,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome36: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'WeakSet',
+ category: 'built-ins',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-weakset-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakSet',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ var obj1 = {};
+ var weakset = new WeakSet();
+
+ weakset.add(obj1);
+ weakset.add(obj1);
+
+ return weakset.has(obj1);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome36: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor arguments',
+ exec() {
+ /*
+ var obj1 = {}, obj2 = {};
+ var weakset = new WeakSet([obj1, obj2]);
+
+ return weakset.has(obj1) && weakset.has(obj2);
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor requires new',
+ exec() {
+ /*
+ new WeakSet();
+ try {
+ WeakSet();
+ return false;
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ chrome36: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor accepts null',
+ exec() {
+ /*
+ new WeakSet(null);
+ return true;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome36: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'constructor invokes add',
+ exec() {
+ /*
+ var passed = false;
+ var _add = WeakSet.prototype.add;
+
+ WeakSet.prototype.add = function(v) {
+ passed = true;
+ };
+
+ new WeakSet([ { } ]);
+ WeakSet.prototype.add = _add;
+
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'iterator closing',
+ exec() {
+ /*
+ var closed = false;
+ var iter = global.__createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ try {
+ new WeakSet(iter);
+ } catch(e){}
+ return closed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome51: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'WeakSet.prototype.add returns this',
+ exec() {
+ /*
+ var weakset = new WeakSet();
+ var obj = {};
+ return weakset.add(obj) === weakset;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ chrome38: true,
+ safari9: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'WeakSet.prototype.delete',
+ exec() {
+ /*
+ return typeof WeakSet.prototype.delete === "function";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome36: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'no WeakSet.prototype.clear method',
+ exec() {
+ /*
+ if (!("clear" in WeakSet.prototype)) {
+ return true;
+ }
+ var s = new WeakSet();
+ var key = {};
+ s.add(key);
+ s.clear();
+ return s.has(key);
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ chrome43: true,
+ safari9: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox46: true,
+ opera10_50: false,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: '.has and .delete methods accept primitives',
+ exec() {
+ /*
+ var s = new WeakSet;
+ return s.has(1) === false
+ && s.delete(1) === false;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome41: true,
+ safari9: true,
+ ejs: null,
+ xs6: null,
+ jxa: null,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: "WeakSet.prototype isn't an instance",
+ exec() {
+ /*
+ new WeakSet();
+ var obj = {};
+ try {
+ WeakSet.prototype.has(obj);
+ }
+ catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome36: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Proxy',
+ category: 'built-ins',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy',
+ note_id: 'proxy-enumerate',
+ note_html:
+ 'The 2015 version of the specification also specifies an "enumerate" handler, which was removed in the 2016 version.',
+ subtests: [
+ {
+ name: 'constructor requires new',
+ exec() {
+ /*
+ new Proxy({}, {});
+ try {
+ Proxy({}, {});
+ return false;
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ firefox25: false,
+ firefox38: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'no "prototype" property',
+ exec() {
+ /*
+ new Proxy({}, {});
+ return !Proxy.hasOwnProperty('prototype');
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"get" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/get',
+ exec() {
+ /*
+ var proxied = { };
+ var proxy = new Proxy(proxied, {
+ get: function (t, k, r) {
+ return t === proxied && k === "foo" && r === proxy && 5;
+ }
+ });
+ return proxy.foo === 5;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"get" handler, instances of proxies',
+ exec() {
+ /*
+ var proxied = { };
+ var proxy = Object.create(new Proxy(proxied, {
+ get: function (t, k, r) {
+ return t === proxied && k === "foo" && r === proxy && 5;
+ }
+ }));
+ return proxy.foo === 5;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox18: {
+ val: false,
+ note_id: 'fx-proxy-get',
+ note_html:
+ 'Firefox 18 up to 37 doesn\'t allow a proxy\'s "get"
handler to be triggered via the prototype chain, unless the proxied object does possess the named property (or the proxy\'s "has"
handler reports it as present).',
+ },
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"get" handler invariants',
+ exec() {
+ /*
+ var passed = false;
+ var proxied = { };
+ var proxy = new Proxy(proxied, {
+ get: function () {
+ passed = true;
+ return 4;
+ }
+ });
+ // The value reported for a property must be the same as the value of the corresponding
+ // target object property if the target object property is a non-writable,
+ // non-configurable own data property.
+ Object.defineProperty(proxied, "foo", { value: 5, enumerable: true });
+ try {
+ proxy.foo;
+ return false;
+ }
+ catch(e) {}
+ // The value reported for a property must be undefined if the corresponding target
+ // object property is a non-configurable own accessor property that has undefined
+ // as its [[Get]] attribute.
+ Object.defineProperty(proxied, "bar",
+ { set: function(){}, enumerable: true });
+ try {
+ proxy.bar;
+ return false;
+ }
+ catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"set" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/set',
+ exec() {
+ /*
+ var proxied = { };
+ var passed = false;
+ var proxy = new Proxy(proxied, {
+ set: function (t, k, v, r) {
+ passed = t === proxied && k + v === "foobar" && r === proxy;
+ }
+ });
+ proxy.foo = "bar";
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"set" handler, instances of proxies',
+ exec() {
+ /*
+ var proxied = { };
+ var passed = false;
+ var proxy = Object.create(new Proxy(proxied, {
+ set: function (t, k, v, r) {
+ passed = t === proxied && k + v === "foobar" && r === proxy;
+ }
+ }));
+ proxy.foo = "bar";
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"set" handler invariants',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // Cannot change the value of a property to be different from the value of
+ // the corresponding target object if the corresponding target object
+ // property is a non-writable, non-configurable own data property.
+ var proxied = {};
+ var proxy = new Proxy(proxied, {
+ set: function () {
+ passed = true;
+ return true;
+ }
+ });
+ Object.defineProperty(proxied, "foo", { value: 2, enumerable: true });
+ proxy.foo = 2;
+ try {
+ proxy.foo = 4;
+ return false;
+ } catch(e) {}
+ // Cannot set the value of a property if the corresponding target
+ // object property is a non-configurable own accessor property
+ // that has undefined as its [[Set]] attribute.
+ Object.defineProperty(proxied, "bar",
+ { get: function(){}, enumerable: true });
+ try {
+ proxy.bar = 2;
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"has" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/has',
+ exec() {
+ /*
+ var proxied = {};
+ var passed = false;
+ "foo" in new Proxy(proxied, {
+ has: function (t, k) {
+ passed = t === proxied && k === "foo";
+ }
+ });
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"has" handler, instances of proxies',
+ exec() {
+ /*
+ var proxied = {};
+ var passed = false;
+ "foo" in Object.create(new Proxy(proxied, {
+ has: function (t, k) {
+ passed = t === proxied && k === "foo";
+ }
+ }));
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"has" handler invariants',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // A property cannot be reported as non-existent, if it exists as a
+ // non-configurable own property of the target object.
+ var proxied = {};
+ var proxy = new Proxy(proxied, {
+ has: function () {
+ passed = true;
+ return false;
+ }
+ });
+ Object.defineProperty(proxied, "foo", { value: 2, writable: true, enumerable: true });
+ try {
+ 'foo' in proxy;
+ return false;
+ } catch(e) {}
+ // A property cannot be reported as non-existent, if it exists as an
+ // own property of the target object and the target object is not extensible.
+ proxied.bar = 2;
+ Object.preventExtensions(proxied);
+ try {
+ 'bar' in proxy;
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"deleteProperty" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty',
+ exec() {
+ /*
+ var proxied = {};
+ var passed = false;
+ delete new Proxy(proxied, {
+ deleteProperty: function (t, k) {
+ passed = t === proxied && k === "foo";
+ }
+ }).foo;
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"deleteProperty" handler invariant',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // A property cannot be reported as deleted, if it exists as a non-configurable
+ // own property of the target object.
+ var proxied = {};
+ Object.defineProperty(proxied, "foo", { value: 2, writable: true, enumerable: true });
+ try {
+ delete new Proxy(proxied, {
+ deleteProperty: function () {
+ passed = true;
+ return true;
+ }
+ }).foo;
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"getOwnPropertyDescriptor" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor',
+ exec() {
+ /*
+ var proxied = {};
+ var fakeDesc = { value: "foo", configurable: true };
+ var returnedDesc = Object.getOwnPropertyDescriptor(
+ new Proxy(proxied, {
+ getOwnPropertyDescriptor: function (t, k) {
+ return t === proxied && k === "foo" && fakeDesc;
+ }
+ }),
+ "foo"
+ );
+ return (returnedDesc.value === fakeDesc.value
+ && returnedDesc.configurable === fakeDesc.configurable
+ && returnedDesc.writable === false
+ && returnedDesc.enumerable === false);
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: {
+ val: false,
+ note_id: 'fx-proxy-getown',
+ note_html:
+ 'From Firefox 18 up to 29, the getOwnPropertyDescriptor
handler can only report non-existent properties if the proxy target is non-extensible rather than extensible',
+ },
+ firefox23: { val: false, note_id: 'fx-proxy-getown' },
+ firefox30: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"getOwnPropertyDescriptor" handler invariants',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // A property cannot be reported as non-existent, if it exists as a non-configurable
+ // own property of the target object.
+ var proxied = {};
+ var proxy = new Proxy(proxied, {
+ getOwnPropertyDescriptor: function () {
+ passed = true;
+ return undefined;
+ }
+ });
+ Object.defineProperty(proxied, "foo", { value: 2, writable: true, enumerable: true });
+ try {
+ Object.getOwnPropertyDescriptor(proxy, "foo");
+ return false;
+ } catch(e) {}
+ // A property cannot be reported as non-existent, if it exists as an own property
+ // of the target object and the target object is not extensible.
+ proxied.bar = 3;
+ Object.preventExtensions(proxied);
+ try {
+ Object.getOwnPropertyDescriptor(proxy, "bar");
+ return false;
+ } catch(e) {}
+ // A property cannot be reported as existent, if it does not exists as an own property
+ // of the target object and the target object is not extensible.
+ try {
+ Object.getOwnPropertyDescriptor(new Proxy(proxied, {
+ getOwnPropertyDescriptor: function() {
+ return { value: 2, configurable: true, writable: true, enumerable: true };
+ }}), "baz");
+ return false;
+ } catch(e) {}
+ // A property cannot be reported as non-configurable, if it does not exists as an own
+ // property of the target object or if it exists as a configurable own property of
+ // the target object.
+ try {
+ Object.getOwnPropertyDescriptor(new Proxy({}, {
+ getOwnPropertyDescriptor: function() {
+ return { value: 2, configurable: false, writable: true, enumerable: true };
+ }}), "baz");
+ return false;
+ } catch(e) {}
+ try {
+ Object.getOwnPropertyDescriptor(new Proxy({baz:1}, {
+ getOwnPropertyDescriptor: function() {
+ return { value: 1, configurable: false, writable: true, enumerable: true };
+ }}), "baz");
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"defineProperty" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty',
+ exec() {
+ /*
+ var proxied = {};
+ var passed = false;
+ Object.defineProperty(
+ new Proxy(proxied, {
+ defineProperty: function (t, k, d) {
+ passed = t === proxied && k === "foo" && d.value === 5;
+ return true;
+ }
+ }),
+ "foo",
+ { value: 5, configurable: true }
+ );
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"defineProperty" handler invariants',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // A property cannot be added, if the target object is not extensible.
+ var proxied = Object.preventExtensions({});
+ var proxy = new Proxy(proxied, {
+ defineProperty: function() {
+ passed = true;
+ return true;
+ }
+ });
+ try {
+ Object.defineProperty(proxy, "foo", { value: 2 });
+ return false;
+ } catch(e) {}
+ // A property cannot be non-configurable, unless there exists a corresponding
+ // non-configurable own property of the target object.
+ try {
+ Object.defineProperty(
+ new Proxy({ bar: true }, {
+ defineProperty: function () {
+ return true;
+ }
+ }),
+ "bar",
+ { value: 5, configurable: false, writable: true, enumerable: true }
+ );
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"getPrototypeOf" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getPrototypeOf',
+ exec() {
+ /*
+ var proxied = {};
+ var fakeProto = {};
+ var proxy = new Proxy(proxied, {
+ getPrototypeOf: function (t) {
+ return t === proxied && fakeProto;
+ }
+ });
+ return Object.getPrototypeOf(proxy) === fakeProto;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"getPrototypeOf" handler invariant',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // If the target object is not extensible, [[GetPrototypeOf]] applied to the proxy object
+ // must return the same value as [[GetPrototypeOf]] applied to the proxy object's target object.
+ try {
+ Object.getPrototypeOf(new Proxy(Object.preventExtensions({}), {
+ getPrototypeOf: function () {
+ passed = true;
+ return {};
+ }
+ }));
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"setPrototypeOf" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/setPrototypeOf',
+ exec() {
+ /*
+ var proxied = {};
+ var newProto = {};
+ var passed = false;
+ Object.setPrototypeOf(
+ new Proxy(proxied, {
+ setPrototypeOf: function (t, p) {
+ passed = t === proxied && p === newProto;
+ return true;
+ }
+ }),
+ newProto
+ );
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"setPrototypeOf" handler invariant',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ Object.setPrototypeOf({},{});
+ // If the target object is not extensible, the argument value must be the
+ // same as the result of [[GetPrototypeOf]] applied to target object.
+ try {
+ Object.setPrototypeOf(
+ new Proxy(Object.preventExtensions({}), {
+ setPrototypeOf: function () {
+ passed = true;
+ return true;
+ }
+ }),{});
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"isExtensible" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/isExtensible',
+ exec() {
+ /*
+ var proxied = {};
+ var passed = false;
+ Object.isExtensible(
+ new Proxy(proxied, {
+ isExtensible: function (t) {
+ passed = t === proxied; return true;
+ }
+ })
+ );
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ firefox2: false,
+ firefox31: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"isExtensible" handler invariant',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // [[IsExtensible]] applied to the proxy object must return the same value
+ // as [[IsExtensible]] applied to the proxy object's target object with the same argument.
+ try {
+ Object.isExtensible(new Proxy({}, {
+ isExtensible: function (t) {
+ passed = true;
+ return false;
+ }
+ }));
+ return false;
+ } catch(e) {}
+ try {
+ Object.isExtensible(new Proxy(Object.preventExtensions({}), {
+ isExtensible: function (t) {
+ return true;
+ }
+ }));
+ return false;
+ } catch(e) {}
+ return true;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ firefox2: false,
+ firefox31: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"preventExtensions" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/preventExtensions',
+ exec() {
+ /*
+ var proxied = {};
+ var passed = false;
+ Object.preventExtensions(
+ new Proxy(proxied, {
+ preventExtensions: function (t) {
+ passed = t === proxied;
+ return Object.preventExtensions(proxied);
+ }
+ })
+ );
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"preventExtensions" handler invariant',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // [[PreventExtensions]] applied to the proxy object only returns true
+ // if [[IsExtensible]] applied to the proxy object's target object is false.
+ try {
+ Object.preventExtensions(new Proxy({}, {
+ preventExtensions: function () {
+ passed = true;
+ return true;
+ }
+ }));
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"ownKeys" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys',
+ exec() {
+ /*
+ var proxied = {};
+ var passed = false;
+ Object.keys(
+ new Proxy(proxied, {
+ ownKeys: function (t) {
+ passed = t === proxied; return [];
+ }
+ })
+ );
+ return passed;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ firefox2: false,
+ firefox18: {
+ val: false,
+ note_id: 'fx-proxy-ownkeys',
+ note_html: 'Available from Firefox 18 up to 33 as the draft standard keys
handler',
+ },
+ firefox23: { val: false, note_id: 'fx-proxy-ownkeys' },
+ firefox33: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ ejs: true,
+ chrome49: true,
+ safari10: true,
+ duktape1_0: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"ownKeys" handler invariant',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // The Type of each result List element is either String or Symbol.
+ try {
+ Object.keys(new Proxy({}, {
+ ownKeys: function () {
+ passed = true;
+ return [2];
+ }}));
+ return false;
+ } catch(e) {}
+ // The result List must contain the keys of all non-configurable own properties of the target object.
+ var proxied = {};
+ Object.defineProperty(proxied, "foo", { value: 2, writable: true, enumerable: true });
+ try {
+ Object.keys(new Proxy(proxied, {
+ ownKeys: function () {
+ return [];
+ }}));
+ return false;
+ } catch(e) {}
+ // If the target object is not extensible, then the result List must contain all the keys
+ // of the own properties of the target object and no other values.
+ try {
+ Object.keys(new Proxy(Object.preventExtensions({b:1}), {
+ ownKeys: function () {
+ return ['a'];
+ }}));
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ firefox2: false,
+ firefox18: { val: false, note_id: 'fx-proxy-ownkeys' },
+ firefox42: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ ejs: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"apply" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/apply',
+ exec() {
+ /*
+ var proxied = function(){};
+ var passed = false;
+ var host = {
+ method: new Proxy(proxied, {
+ apply: function (t, thisArg, args) {
+ passed = t === proxied && thisArg === host && args + "" === "foo,bar";
+ }
+ })
+ };
+ host.method("foo", "bar");
+ return passed;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"apply" handler invariant',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy(function(){}, {
+ apply: function () { passed = true; }
+ })();
+ // A Proxy exotic object only has a [[Call]] internal method if the
+ // initial value of its [[ProxyTarget]] internal slot is an object
+ // that has a [[Call]] internal method.
+ try {
+ new Proxy({}, {
+ apply: function () {}
+ })();
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ chrome50: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"construct" handler',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/construct',
+ exec() {
+ /*
+ var proxied = function(){};
+ var passed = false;
+ new new Proxy(proxied, {
+ construct: function (t, args) {
+ passed = t === proxied && args + "" === "foo,bar";
+ return {};
+ }
+ })("foo","bar");
+ return passed;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: '"construct" handler invariants',
+ exec() {
+ /*
+ var passed = false;
+ new Proxy({},{});
+ // A Proxy exotic object only has a [[Construct]] internal method if the
+ // initial value of its [[ProxyTarget]] internal slot is an object
+ // that has a [[Construct]] internal method.
+ try {
+ new new Proxy({}, {
+ construct: function (t, args) {
+ return {};
+ }
+ })();
+ return false;
+ } catch(e) {}
+ // The result of [[Construct]] must be an Object.
+ try {
+ new new Proxy(function(){}, {
+ construct: function (t, args) {
+ passed = true;
+ return 5;
+ }
+ })();
+ return false;
+ } catch(e) {}
+ return passed;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox31: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Proxy.revocable',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/revocable',
+ exec() {
+ /*
+ var obj = Proxy.revocable({}, { get: function() { return 5; } });
+ var passed = (obj.proxy.foo === 5);
+ obj.revoke();
+ try {
+ obj.proxy.foo;
+ } catch(e) {
+ passed &= e instanceof TypeError;
+ }
+ return passed;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.isArray support',
+ exec() {
+ /*
+ return Array.isArray(new Proxy([], {}));
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_5: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'JSON.stringify support',
+ exec() {
+ /*
+ return JSON.stringify(new Proxy(['foo'], {})) === '["foo"]';
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ firefox2: false,
+ firefox18: true, // a bug in FF18
+ firefox21: false,
+ firefox40: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_5: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: "Proxy, internal 'get' calls",
+ category: 'misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/get',
+ subtests: [
+ {
+ name: 'ToPrimitive',
+ exec() {
+ /*
+ // ToPrimitive -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({toString:Function()}, { get: function(o, k) { get.push(k); return o[k]; }});
+ p + 3;
+ return get[0] === Symbol.toPrimitive && get.slice(1) + '' === "valueOf,toString";
+ */
+ },
+ res: {
+ xs6: true,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox44: true,
+ opera10_50: false,
+ ejs: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'CreateListFromArrayLike',
+ exec() {
+ /*
+ // CreateListFromArrayLike -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({length:2, 0:0, 1:0}, { get: function(o, k) { get.push(k); return o[k]; }});
+ Function.prototype.apply({}, p);
+ return get + '' === "length,0,1";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'instanceof operator',
+ exec() {
+ /*
+ // InstanceofOperator -> GetMethod -> GetV -> [[Get]]
+ // InstanceofOperator -> OrdinaryHasInstance -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy(Function(), { get: function(o, k) { get.push(k); return o[k]; }});
+ ({}) instanceof p;
+ return get[0] === Symbol.hasInstance && get.slice(1) + '' === "prototype";
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox50: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'HasBinding',
+ exec() {
+ /*
+ // HasBinding -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({foo:1}, { get: function(o, k) { get.push(k); return o[k]; }});
+ p[Symbol.unscopables] = p;
+ with(p) {
+ typeof foo;
+ }
+ return get[0] === Symbol.unscopables && get.slice(1) + '' === "foo";
+ */
+ },
+ res: {
+ xs6: true,
+ ejs: { val: false, note_id: 'ejs-no-with' },
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome49: true,
+ safari10: true,
+ ie11: false,
+ edge14: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'CreateDynamicFunction',
+ exec() {
+ /*
+ // CreateDynamicFunction -> GetPrototypeFromConstructor -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy(Function, { get: function(o, k) { get.push(k); return o[k]; }});
+ new p;
+ return get + '' === "prototype";
+ */
+ },
+ res: {
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'ClassDefinitionEvaluation',
+ exec() {
+ /*
+ // ClassDefinitionEvaluation -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy(Function(), { get: function(o, k) { get.push(k); return o[k]; }});
+ class C extends p {}
+ return get + '' === "prototype";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'IteratorComplete, IteratorValue',
+ exec() {
+ /*
+ // IteratorComplete -> Get -> [[Get]]
+ // IteratorValue -> Get -> [[Get]]
+ var get = [];
+ var iterable = {};
+ iterable[Symbol.iterator] = function() {
+ return {
+ next: function() {
+ return new Proxy({ value: 2, done: false }, { get: function(o, k) { get.push(k); return o[k]; }});
+ }
+ };
+ }
+ var i = 0;
+ for(var e of iterable) {
+ if (++i >= 2) break;
+ }
+ return get + '' === "done,value,done,value";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'ToPropertyDescriptor',
+ exec() {
+ /*
+ // ToPropertyDescriptor -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({
+ enumerable: true, configurable: true, value: true,
+ writable: true, get: Function(), set: Function()
+ }, { get: function(o, k) { get.push(k); return o[k]; }});
+ try {
+ // This will throw, since it will have true for both "get" and "value",
+ // but not before performing a Get on every property.
+ Object.defineProperty({}, "foo", p);
+ } catch(e) {
+ return get + '' === "enumerable,configurable,value,writable,get,set";
+ }
+ */
+ },
+ res: {
+ ejs: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Object.assign',
+ exec() {
+ /*
+ // Object.assign -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({foo:1, bar:2}, { get: function(o, k) { get.push(k); return o[k]; }});
+ Object.assign({}, p);
+ return get + '' === "foo,bar";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Object.defineProperties',
+ exec() {
+ /*
+ // Object.defineProperties -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({foo:{}, bar:{}}, { get: function(o, k) { get.push(k); return o[k]; }});
+ Object.defineProperties({}, p);
+ return get + '' === "foo,bar";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Function.prototype.bind',
+ exec() {
+ /*
+ // Function.prototype.bind -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy(Function(), { get: function(o, k) { get.push(k); return o[k]; }});
+ Function.prototype.bind.call(p);
+ return get + '' === "length,name";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Error.prototype.toString',
+ exec() {
+ /*
+ // Error.prototype.toString -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});
+ Error.prototype.toString.call(p);
+ return get + '' === "name,message";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'String.raw',
+ exec() {
+ /*
+ // String.raw -> Get -> [[Get]]
+ var get = [];
+ var raw = new Proxy({length: 2, 0: '', 1: ''}, { get: function(o, k) { get.push(k); return o[k]; }});
+ var p = new Proxy({raw: raw}, { get: function(o, k) { get.push(k); return o[k]; }});
+ String.raw(p);
+ return get + '' === "raw,length,0,1";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp constructor',
+ exec() {
+ /*
+ // RegExp -> Get -> [[Get]]
+ var get = [];
+ var re = { constructor: null };
+ re[Symbol.match] = true;
+ var p = new Proxy(re, { get: function(o, k) { get.push(k); return o[k]; }});
+ RegExp(p);
+ return get[0] === Symbol.match && get.slice(1) + '' === "constructor,source,flags";
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ ie11: false,
+ edge14: edge.experimental,
+ chrome50: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype.flags',
+ exec() {
+ /*
+ // RegExp.prototype.flags -> Get -> [[Get]]
+ var expected = [];
+ // Sorted alphabetically by shortname – "gimsuy".
+ if ('hasIndices' in RegExp.prototype) expected.push('hasIndices');
+ if ('global' in RegExp.prototype) expected.push('global');
+ if ('ignoreCase' in RegExp.prototype) expected.push('ignoreCase');
+ if ('multiline' in RegExp.prototype) expected.push('multiline');
+ if ('dotAll' in RegExp.prototype) expected.push('dotAll');
+ if ('unicode' in RegExp.prototype) expected.push('unicode');
+ if ('unicodeSets' in RegExp.prototype) expected.push('unicodeSets');
+ if ('sticky' in RegExp.prototype) expected.push('sticky');
+
+ var actual = [];
+ var p = new Proxy({}, { get: function(o, k) { actual.push(k); return o[k]; }});
+ Object.getOwnPropertyDescriptor(RegExp.prototype, 'flags').get.call(p);
+ if (expected.length !== actual.length) return false;
+ for (var i = 0; i < expected.length; i++) {
+ if (expected[i] !== actual[i]) return false;
+ }
+ return true;
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox37: true,
+ firefox39: false,
+ firefox46: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ ie11: false,
+ edge14: edge.experimental,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ graalvm22_2: graalvm.es6flag,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype.test',
+ exec() {
+ /*
+ // RegExp.prototype.test -> RegExpExec -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
+ RegExp.prototype.test.call(p);
+ return get + '' === "exec";
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox46: true,
+ opera10_50: false,
+ ie11: false,
+ edge14: edge.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype.toString',
+ exec() {
+ /*
+ // RegExp.prototype.toString -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});
+ RegExp.prototype.toString.call(p);
+ return get + '' === "source,flags";
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox39: true,
+ opera10_50: false,
+ ie11: false,
+ edge14: edge.experimental,
+ chrome50: true,
+ xs6: null,
+ ejs: null,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype[Symbol.match]',
+ exec() {
+ /*
+ // RegExp.prototype[Symbol.match] -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
+ RegExp.prototype[Symbol.match].call(p);
+ p.global = true;
+ RegExp.prototype[Symbol.match].call(p);
+ var str = get + '';
+ return str === "global,exec,global,unicode,exec" || str === 'flags,exec,flags,exec';
+ */
+ },
+ res: {
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype[Symbol.replace]',
+ exec() {
+ /*
+ // RegExp.prototype[Symbol.replace] -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
+ RegExp.prototype[Symbol.replace].call(p);
+ p.global = true;
+ RegExp.prototype[Symbol.replace].call(p);
+ var str = get + '';
+ return str === "global,exec,global,unicode,exec" || str === 'flags,exec,flags,exec';
+ */
+ },
+ res: {
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype[Symbol.search]',
+ exec() {
+ /*
+ // RegExp.prototype[Symbol.search] -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({ exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
+ RegExp.prototype[Symbol.search].call(p);
+ return get + '' === "lastIndex,exec,lastIndex";
+ */
+ },
+ note_id: 'regexp-prototype-symbolsearch',
+ note_html:
+ "The specification for this feature was updated after ES6 was published. This test reflects the updated spec, which is implemented by the latest browsers.",
+ res: {
+ ie11: false,
+ edge14: false,
+ firefox2: false,
+ firefox49: false,
+ firefox55: true,
+ opera10_50: false,
+ chrome51: false,
+ chrome56: true,
+ node8: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_4_0: true,
+ safari12: true,
+ safaritp: true,
+ webkit: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype[Symbol.split]',
+ exec() {
+ /*
+ // RegExp.prototype[Symbol.split] -> Get -> [[Get]]
+ var get = [];
+ var constructor = Function();
+ constructor[Symbol.species] = Object;
+ var p = new Proxy({ constructor: constructor, flags: '', exec: function() { return null; } }, { get: function(o, k) { get.push(k); return o[k]; }});
+ RegExp.prototype[Symbol.split].call(p, "");
+ return get + '' === "constructor,flags,exec";
+ */
+ },
+ res: {
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome51: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.from',
+ exec() {
+ /*
+ // Array.from -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({length: 2, 0: '', 1: ''}, { get: function(o, k) { get.push(k); return o[k]; }});
+ Array.from(p);
+ return get[0] === Symbol.iterator && get.slice(1) + '' === "length,0,1";
+ */
+ },
+ res: {
+ ejs: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.concat',
+ exec() {
+ /*
+ // Array.prototype.concat -> Get -> [[Get]]
+ var get = [];
+ var arr = [1];
+ arr.constructor = void undefined;
+ var p = new Proxy(arr, { get: function(o, k) { get.push(k); return o[k]; }});
+ Array.prototype.concat.call(p,p);
+ return get[0] === "constructor"
+ && get[1] === Symbol.isConcatSpreadable
+ && get[2] === "length"
+ && get[3] === "0"
+ && get[4] === get[1] && get[5] === get[2] && get[6] === get[3]
+ && get.length === 7;
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: true,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype iteration methods',
+ exec() {
+ /*
+ // Array.prototype methods -> Get -> [[Get]]
+ var methods = ['copyWithin', 'every', 'fill', 'filter', 'find', 'findIndex', 'forEach',
+ 'indexOf', 'join', 'lastIndexOf', 'map', 'reduce', 'reduceRight', 'some'];
+ var get;
+ var p = new Proxy({length: 2, 0: '', 1: ''}, { get: function(o, k) { get.push(k); return o[k]; }});
+ for(var i = 0; i < methods.length; i+=1) {
+ get = [];
+ Array.prototype[methods[i]].call(p, Function());
+ if (get + '' !== (
+ methods[i] === 'fill' ? "length" :
+ methods[i] === 'every' ? "length,0" :
+ methods[i] === 'lastIndexOf' || methods[i] === 'reduceRight' ? "length,1,0" :
+ "length,0,1"
+ )) {
+ return false;
+ }
+ }
+ return true;
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ chrome51: true,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.pop',
+ exec() {
+ /*
+ // Array.prototype.pop -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy([0,1,2,3], { get: function(o, k) { get.push(k); return o[k]; }});
+ Array.prototype.pop.call(p);
+ return get + '' === "length,3";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.reverse',
+ exec() {
+ /*
+ // Array.prototype.reverse -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy([0,,2,,4,,], { get: function(o, k) { get.push(k); return o[k]; }});
+ Array.prototype.reverse.call(p);
+ return get + '' === "length,0,4,2";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.shift',
+ exec() {
+ /*
+ // Array.prototype.shift -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy([0,1,2,3], { get: function(o, k) { get.push(k); return o[k]; }});
+ Array.prototype.shift.call(p);
+ return get + '' === "length,0,1,2,3";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.splice',
+ exec() {
+ /*
+ // Array.prototype.splice -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy([0,1,2,3], { get: function(o, k) { get.push(k); return o[k]; }});
+ Array.prototype.splice.call(p,1,1);
+ Array.prototype.splice.call(p,1,0,1);
+ return get + '' === "length,constructor,1,2,3,length,constructor,2,1";
+ */
+ },
+ res: {
+ closure: true,
+ ejs: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.toString',
+ exec() {
+ /*
+ // Array.prototype.toString -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({ join:Function() }, { get: function(o, k) { get.push(k); return o[k]; }});
+ Array.prototype.toString.call(p);
+ return get + '' === "join";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'JSON.stringify',
+ exec() {
+ /*
+ // JSON.stringify -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});
+ JSON.stringify(p);
+ return get + '' === "toJSON";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Promise resolve functions',
+ exec() {
+ /*
+ // Promise resolve functions -> Get -> [[Get]]
+ var get = [];
+ var p = new Proxy({}, { get: function(o, k) { get.push(k); return o[k]; }});
+ new Promise(function(resolve){ resolve(p); });
+ return get + '' === "then";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'String.prototype.match',
+ exec() {
+ /*
+ // String.prototype.match -> Get -> [[Get]]
+ var get = [];
+ var proxied = {};
+ proxied[Symbol.toPrimitive] = Function();
+ var p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});
+ "".match(p);
+ return get[0] === Symbol.match && get[1] === Symbol.toPrimitive && get.length === 2;
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'String.prototype.replace',
+ exec() {
+ /*
+ // String.prototype.replace functions -> Get -> [[Get]]
+ var get = [];
+ var proxied = {};
+ proxied[Symbol.toPrimitive] = Function();
+ var p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});
+ "".replace(p);
+ return get[0] === Symbol.replace && get[1] === Symbol.toPrimitive && get.length === 2;
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome50: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'String.prototype.search',
+ exec() {
+ /*
+ // String.prototype.search functions -> Get -> [[Get]]
+ var get = [];
+ var proxied = {};
+ proxied[Symbol.toPrimitive] = Function();
+ var p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});
+ "".search(p);
+ return get[0] === Symbol.search && get[1] === Symbol.toPrimitive && get.length === 2;
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'String.prototype.split',
+ exec() {
+ /*
+ // String.prototype.split functions -> Get -> [[Get]]
+ var get = [];
+ var proxied = {};
+ proxied[Symbol.toPrimitive] = Function();
+ var p = new Proxy(proxied, { get: function(o, k) { get.push(k); return o[k]; }});
+ "".split(p);
+ return get[0] === Symbol.split && get[1] === Symbol.toPrimitive && get.length === 2;
+ */
+ },
+ res: {
+ ie11: false,
+ edge15: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome50: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Date.prototype.toJSON',
+ exec() {
+ /*
+ // Date.prototype.toJSON -> ToPrimitive -> Get -> [[Get]]
+ // Date.prototype.toJSON -> Invoke -> GetMethod -> GetV -> [[Get]]
+ var get = [];
+ var p = new Proxy({toString:Function(),toISOString:Function()}, { get: function(o, k) { get.push(k); return o[k]; }});
+ Date.prototype.toJSON.call(p);
+ return get[0] === Symbol.toPrimitive && get.slice(1) + '' === "valueOf,toString,toISOString";
+ */
+ },
+ res: {
+ xs6: true,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox44: true,
+ opera10_50: false,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: "Proxy, internal 'set' calls",
+ category: 'misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/set',
+ subtests: [
+ {
+ name: 'Object.assign',
+ exec() {
+ /*
+ // Object.assign -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy({}, { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ Object.assign(p, { foo: 1, bar: 2 });
+ return set + '' === "foo,bar";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.from',
+ exec() {
+ /*
+ // Array.from -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy({}, { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ Array.from.call(function(){ return p; }, {length:2, 0:1, 1:2});
+ return set + '' === "length";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ ejs: true,
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.of',
+ exec() {
+ /*
+ // Array.from -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy({}, { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ Array.of.call(function(){ return p; }, 1, 2, 3);
+ return set + '' === "length";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ ejs: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.copyWithin',
+ exec() {
+ /*
+ // Array.prototype.copyWithin -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy([1,2,3,4,5,6], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ p.copyWithin(0, 3);
+ return set + '' === "0,1,2";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.fill',
+ exec() {
+ /*
+ // Array.prototype.fill -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy([1,2,3,4,5,6], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ p.fill(0, 3);
+ return set + '' === "3,4,5";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.pop',
+ exec() {
+ /*
+ // Array.prototype.pop -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy([], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ p.pop();
+ return set + '' === "length";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.push',
+ exec() {
+ /*
+ // Array.prototype.push -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy([], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ p.push(0,0,0);
+ return set + '' === "0,1,2,length";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.reverse',
+ exec() {
+ /*
+ // Array.prototype.reverse -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy([0,0,0,,], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ p.reverse();
+ return set + '' === "3,1,2";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.shift',
+ exec() {
+ /*
+ // Array.prototype.shift -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy([0,0,,0], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ p.shift();
+ return set + '' === "0,2,length";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ firefox21: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.splice',
+ exec() {
+ /*
+ // Array.prototype.splice -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy([1,2,3], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ p.splice(1,0,0);
+ return set + '' === "3,2,1,length";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ firefox21: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.unshift',
+ exec() {
+ /*
+ // Array.prototype.unshift -> Set -> [[Set]]
+ var set = [];
+ var p = new Proxy([0,0,,0], { set: function(o, k, v) { set.push(k); o[k] = v; return true; }});
+ p.unshift(0,1);
+ return set + '' === "5,3,2,0,1,length";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ firefox21: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: "Proxy, internal 'defineProperty' calls",
+ category: 'misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/defineProperty',
+ subtests: [
+ {
+ name: '[[Set]]',
+ exec() {
+ /*
+ // [[Set]] -> [[DefineOwnProperty]]
+ var def = [];
+ var p = new Proxy({foo:1, bar:2}, { defineProperty: function(o, v, desc) { def.push(v); Object.defineProperty(o, v, desc); return true; }});
+ p.foo = 2; p.bar = 4;
+ return def + '' === "foo,bar";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ chrome49: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'SetIntegrityLevel',
+ exec() {
+ /*
+ // SetIntegrityLevel -> DefinePropertyOrThrow -> [[DefineOwnProperty]]
+ var def = [];
+ var p = new Proxy({foo:1, bar:2}, { defineProperty: function(o, v, desc) { def.push(v); Object.defineProperty(o, v, desc); return true; }});
+ Object.freeze(p);
+ return def + '' === "foo,bar";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: "Proxy, internal 'deleteProperty' calls",
+ category: 'misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/deleteProperty',
+ subtests: [
+ {
+ name: 'Array.prototype.copyWithin',
+ exec() {
+ /*
+ // Array.prototype.copyWithin -> DeletePropertyOrThrow -> [[Delete]]
+ var del = [];
+ var p = new Proxy([0,0,0,,,,], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
+ p.copyWithin(0,3);
+ return del + '' === "0,1,2";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.pop',
+ exec() {
+ /*
+ // Array.prototype.pop -> DeletePropertyOrThrow -> [[Delete]]
+ var del = [];
+ var p = new Proxy([0,0,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
+ p.pop();
+ return del + '' === "2";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ firefox21: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.reverse',
+ exec() {
+ /*
+ // Array.prototype.reverse -> DeletePropertyOrThrow -> [[Delete]]
+ var del = [];
+ var p = new Proxy([0,,2,,4,,], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
+ p.reverse();
+ return del + '' === "0,4,2";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ firefox21: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.shift',
+ exec() {
+ /*
+ // Array.prototype.shift -> DeletePropertyOrThrow -> [[Delete]]
+ var del = [];
+ var p = new Proxy([0,,0,,0,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
+ p.shift();
+ return del + '' === "0,2,5";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ firefox21: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.splice',
+ exec() {
+ /*
+ // Array.prototype.splice -> DeletePropertyOrThrow -> [[Delete]]
+ var del = [];
+ var p = new Proxy([0,0,0,0,,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
+ p.splice(2,2,0);
+ return del + '' === "3,5";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ firefox21: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.unshift',
+ exec() {
+ /*
+ // Array.prototype.unshift -> DeletePropertyOrThrow -> [[Delete]]
+ var del = [];
+ var p = new Proxy([0,0,,0,,0], { deleteProperty: function(o, v) { del.push(v); return delete o[v]; }});
+ p.unshift(0);
+ return del + '' === "5,3";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox18: true,
+ firefox21: false,
+ firefox40: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: "Proxy, internal 'getOwnPropertyDescriptor' calls",
+ category: 'misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/getOwnPropertyDescriptor',
+ subtests: [
+ {
+ name: '[[Set]]',
+ exec() {
+ /*
+ // [[Set]] -> [[GetOwnProperty]]
+ var gopd = [];
+ var p = new Proxy({},
+ { getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});
+ p.foo = 1; p.bar = 1;
+ return gopd + '' === "foo,bar";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ chrome49: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Object.assign',
+ exec() {
+ /*
+ // Object.assign -> [[GetOwnProperty]]
+ var gopd = [];
+ var p = new Proxy({foo:1, bar:2},
+ { getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});
+ Object.assign({}, p);
+ return gopd + '' === "foo,bar";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Object.prototype.hasOwnProperty',
+ exec() {
+ /*
+ // Object.prototype.hasOwnProperty -> HasOwnProperty -> [[GetOwnProperty]]
+ var gopd = [];
+ var p = new Proxy({foo:1, bar:2},
+ { getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});
+ p.hasOwnProperty('garply');
+ return gopd + '' === "garply";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox33: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Function.prototype.bind',
+ exec() {
+ /*
+ // Function.prototype.bind -> HasOwnProperty -> [[GetOwnProperty]]
+ var gopd = [];
+ var p = new Proxy(Function(),
+ { getOwnPropertyDescriptor: function(o, v) { gopd.push(v); return Object.getOwnPropertyDescriptor(o, v); }});
+ p.bind();
+ return gopd + '' === "length";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: "Proxy, internal 'ownKeys' calls",
+ category: 'misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler/ownKeys',
+ subtests: [
+ {
+ name: 'SetIntegrityLevel',
+ exec() {
+ /*
+ // SetIntegrityLevel -> [[OwnPropertyKeys]]
+ var ownKeysCalled = 0;
+ var p = new Proxy({}, { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});
+ Object.freeze(p);
+ return ownKeysCalled === 1;
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox33: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'TestIntegrityLevel',
+ exec() {
+ /*
+ // TestIntegrityLevel -> [[OwnPropertyKeys]]
+ var ownKeysCalled = 0;
+ var p = new Proxy(Object.preventExtensions({}), { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});
+ Object.isFrozen(p);
+ return ownKeysCalled === 1;
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox33: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'SerializeJSONObject',
+ exec() {
+ /*
+ // SerializeJSONObject -> EnumerableOwnNames -> [[OwnPropertyKeys]]
+ var ownKeysCalled = 0;
+ var p = new Proxy({}, { ownKeys: function(o) { ownKeysCalled++; return Object.keys(o); }});
+ JSON.stringify({a:p,b:p});
+ return ownKeysCalled === 2;
+ */
+ },
+ res: {
+ ejs: true,
+ firefox2: false,
+ firefox33: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Reflect',
+ category: 'built-ins',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-reflection',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect',
+ note_id: 'reflect-enumerate',
+ note_html:
+ 'The 2015 version of the specification also specifies Reflect.enumerate, which was removed in the 2016 version.',
+ subtests: [
+ {
+ name: 'Reflect.get',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/get',
+ exec() {
+ /*
+ return Reflect.get({ qux: 987 }, "qux") === 987;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ safari10: true,
+ xs6: true,
+ chrome49: true,
+ duktape1_0: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.set',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/set',
+ exec() {
+ /*
+ var obj = {};
+ Reflect.set(obj, "quux", 654);
+ return obj.quux === 654;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape1_0: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.has',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/has',
+ exec() {
+ /*
+ return Reflect.has({ qux: 987 }, "qux");
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ duktape1_0: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.deleteProperty',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/deleteProperty',
+ exec() {
+ /*
+ var obj = { bar: 456 };
+ Reflect.deleteProperty(obj, "bar");
+ return !("bar" in obj);
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ duktape1_0: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.getOwnPropertyDescriptor',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getOwnPropertyDescriptor',
+ exec() {
+ /*
+ var obj = { baz: 789 };
+ var desc = Reflect.getOwnPropertyDescriptor(obj, "baz");
+ return desc.value === 789 &&
+ desc.configurable && desc.writable && desc.enumerable;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ safari10: true,
+ xs6: true,
+ chrome49: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.defineProperty',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/defineProperty',
+ exec() {
+ /*
+ var obj = {};
+ Reflect.defineProperty(obj, "foo", { value: 123 });
+ return obj.foo === 123 &&
+ Reflect.defineProperty(Object.freeze({}), "foo", { value: 123 }) === false;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ chrome49: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.getPrototypeOf',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/getPrototypeOf',
+ exec() {
+ /*
+ return Reflect.getPrototypeOf([]) === Array.prototype;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.setPrototypeOf',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/setPrototypeOf',
+ exec() {
+ /*
+ var obj = {};
+ Reflect.setPrototypeOf(obj, Array.prototype);
+ return obj instanceof Array;
+ */
+ },
+ res: {
+ babel6corejs2: { val: false, note_id: 'compiler-proto' },
+ closure: { val: false, note_id: 'compiler-proto' },
+ typescript1corejs2: { val: false, note_id: 'compiler-proto' },
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ es6shim: { val: false, note_id: 'compiler-proto' },
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.isExtensible',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/isExtensible',
+ exec() {
+ /*
+ return Reflect.isExtensible({}) &&
+ !Reflect.isExtensible(Object.preventExtensions({}));
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.preventExtensions',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/preventExtensions',
+ exec() {
+ /*
+ var obj = {};
+ Reflect.preventExtensions(obj);
+ return !Object.isExtensible(obj);
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.ownKeys, string keys',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys',
+ exec() {
+ /*
+ var obj = Object.create({ C: true });
+ obj.A = true;
+ Object.defineProperty(obj, 'B', { value: true, enumerable: false });
+
+ return Reflect.ownKeys(obj).sort() + '' === "A,B";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ duktape1_0: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.ownKeys, symbol keys',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys',
+ exec() {
+ /*
+ var s1 = Symbol(), s2 = Symbol(), s3 = Symbol();
+ var proto = {};
+ proto[s1] = true;
+ var obj = Object.create(proto);
+ obj[s2] = true;
+ Object.defineProperty(obj, s3, { value: true, enumerable: false });
+
+ var keys = Reflect.ownKeys(obj);
+ return keys.indexOf(s2) >-1 && keys.indexOf(s3) >-1 && keys.length === 2;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ closure20190301: false,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ duktape1_0: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.apply',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/apply',
+ exec() {
+ /*
+ return Reflect.apply(Array.prototype.push, [1,2], [3,4,5]) === 5;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.construct',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/construct',
+ exec() {
+ /*
+ return Reflect.construct(function(a, b, c) {
+ this.qux = a + b + c;
+ }, ["foo", "bar", "baz"]).qux === "foobarbaz";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.construct sets new.target meta-property',
+ exec() {
+ /*
+ return Reflect.construct(function(a, b, c) {
+ if (new.target === Object) {
+ this.qux = a + b + c;
+ }
+ }, ["foo", "bar", "baz"], Object).qux === "foobarbaz";
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ xs6: true,
+ ejs: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.construct creates instances from third argument',
+ exec() {
+ /*
+ function F(){}
+ var obj = Reflect.construct(function(){ this.y = 1; }, [], F);
+ return obj.y === 1 && obj instanceof F;
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ es6shim: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox44: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.construct, Array subclassing',
+ exec() {
+ /*
+ function F(){}
+ var obj = Reflect.construct(Array, [], F);
+ obj[2] = 'foo';
+ return obj.length === 3 && obj instanceof F;
+ */
+ },
+ res: {
+ ejs: null,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: null,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.construct, RegExp subclassing',
+ exec() {
+ /*
+ function F(){}
+ var obj = Reflect.construct(RegExp, ["baz","g"], F);
+ return RegExp.prototype.exec.call(obj, "foobarbaz")[0] === "baz"
+ && obj.lastIndex === 9 && obj instanceof F;
+ */
+ },
+ res: {
+ ejs: null,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ firefox46: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: null,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.construct, Function subclassing',
+ exec() {
+ /*
+ function F(){}
+ var obj = Reflect.construct(Function, ["return 2"], F);
+ return obj() === 2 && obj instanceof F;
+ */
+ },
+ res: {
+ ejs: null,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: null,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.construct, Promise subclassing',
+ exec() {
+ /*
+ function F(){}
+ var p1 = Reflect.construct(Promise,[function(resolve, reject) { resolve("foo"); }], F);
+ var p2 = Reflect.construct(Promise,[function(resolve, reject) { reject("quux"); }], F);
+ var score = +(p1 instanceof F && p2 instanceof F);
+
+ function thenFn(result) { score += (result === "foo"); check(); }
+ function catchFn(result) { score += (result === "quux"); check(); }
+ function shouldNotRun(result) { score = -Infinity; }
+
+ p1.then = p2.then = Promise.prototype.then;
+ p1.catch = p2.catch = Promise.prototype.catch;
+
+ p1.then(thenFn, shouldNotRun);
+ p2.then(shouldNotRun, catchFn);
+ p1.catch(shouldNotRun);
+ p2.catch(catchFn);
+
+ function check() {
+ if (score === 4) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ ejs: null,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ xs6: null,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'block-level function declaration',
+ category: 'bindings',
+ significance: 'small',
+ note_id: 'block-level-function',
+ note_html:
+ 'Note that prior to ES6, it was recommended that ES5 implementations forbid block-level declarations in strict mode.',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-functiondeclarationinstantiation',
+ exec() {
+ /*
+ 'use strict';
+ if (f() !== 1) return false;
+ function f() { return 1; }
+ {
+ if (f() !== 2) return false;
+ function f() { return 2; }
+ if (f() !== 2) return false;
+ }
+ if (f() !== 1) return false;
+ return true;
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ tr: true,
+ closure: true,
+ ie11: true,
+ firefox2: false,
+ firefox46: true,
+ opera10_50: false,
+ chrome21: chrome.experimental,
+ chrome41: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'destructuring, declarations',
+ category: 'syntax',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-assignment',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment',
+ subtests: [
+ {
+ name: 'with arrays',
+ exec() {
+ /*
+ var [a, , [b], c] = [5, null, [6]];
+ return a === 5 && b === 6 && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with sparse arrays',
+ exec() {
+ /*
+ var [a, , b] = [,,,];
+ return a === void undefined && b === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with strings',
+ exec() {
+ /*
+ var [a, b, c] = "ab";
+ return a === "a" && b === "b" && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with astral plane strings',
+ exec() {
+ /*
+ var [c] = "𠮷𠮶";
+ return c === "𠮷";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generator instances',
+ exec() {
+ /*
+ var [a, b, c] = (function*(){ yield 1; yield 2; }());
+ return a === 1 && b === 2 && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ safari10: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generic iterables',
+ exec() {
+ /*
+ var [a, b, c] = global.__createIterableObject([1, 2]);
+ return a === 1 && b === 2 && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with instances of generic iterables',
+ exec() {
+ /*
+ var [a, b, c] = Object.create(global.__createIterableObject([1, 2]));
+ return a === 1 && b === 2 && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'iterator closing',
+ exec() {
+ /*
+ var closed = false;
+ var iter = global.__createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ var [a, b] = iter;
+ return closed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome51: true,
+ node6_5: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'trailing commas in iterable patterns',
+ exec() {
+ /*
+ var [a,] = [1];
+ return a === 1;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with objects',
+ exec() {
+ /*
+ var {c, x:d, e} = {c:7, x:8};
+ return c === 7 && d === 8 && e === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: {
+ val: true,
+ note_id: 'ff11-object-destructuring',
+ note_html:
+ 'Firefox < 16 incorrectly treats ({f,g} = {f:9,g:10})
as assigning to global variables instead of locals.',
+ },
+ firefox15: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'object destructuring with primitives',
+ exec() {
+ /*
+ var {toFixed} = 2;
+ var {slice} = '';
+ return toFixed === Number.prototype.toFixed
+ && slice === String.prototype.slice;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'trailing commas in object patterns',
+ exec() {
+ /*
+ var {a,} = {a:1};
+ return a === 1;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'throws on null and undefined',
+ exec() {
+ /*
+ try {
+ var {a} = null;
+ return false;
+ } catch(e) {
+ if (!(e instanceof TypeError))
+ return false;
+ }
+ try {
+ var {b} = void undefined;
+ return false;
+ } catch(e) {
+ if (!(e instanceof TypeError))
+ return false;
+ }
+ return true;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'computed properties',
+ exec() {
+ /*
+ var qux = "corge";
+ var { [qux]: grault } = { corge: "garply" };
+ return grault === "garply";
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ tr: true,
+ es6tr: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ safari10: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'multiples in a single var statement',
+ exec() {
+ /*
+ var [a,b] = [5,6], {c,d} = {c:7,d:8};
+ return a === 5 && b === 6 && c === 7 && d === 8;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'nested',
+ exec() {
+ /*
+ var [e, {x:f, g}] = [9, {x:10}];
+ var {h, x:[i]} = {h:11, x:[12]};
+ return e === 9 && f === 10 && g === void undefined
+ && h === 11 && i === 12;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'in for-in loop heads',
+ exec() {
+ /*
+ for(var [i, j, k] in { qux: 1 }) {
+ return i === "q" && j === "u" && k === "x";
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'in for-of loop heads',
+ exec() {
+ /*
+ for(var [i, j, k] of [[1,2,3]]) {
+ return i === 1 && j === 2 && k === 3;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ closure: true,
+ firefox2: false,
+ firefox13: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'in catch heads',
+ exec() {
+ /*
+ try {
+ throw [1,2];
+ } catch([i,j]) {
+ try {
+ throw { k: 3, l: 4 };
+ } catch({k, l}) {
+ return i === 1 && j === 2 && k === 3 && l === 4;
+ }
+ }
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ tr: true,
+ jsx: true,
+ closure: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ ie11: false,
+ edge14: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.catchDestructuring,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'rest',
+ exec() {
+ /*
+ var [a, ...b] = [3, 4, 5];
+ var [c, ...d] = [6];
+ return a === 3 && b instanceof Array && (b + "") === "4,5" &&
+ c === 6 && d instanceof Array && d.length === 0;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'defaults',
+ exec() {
+ /*
+ var {a = 1, b = 0, z:c = 3} = {b:2, z:undefined};
+ var [d = 0, e = 5, f = 6] = [4,,undefined];
+ return a === 1 && b === 2 && c === 3
+ && d === 4 && e === 5 && f === 6;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ closure: true,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox47: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'defaults, let temporal dead zone',
+ exec() {
+ /*
+ var {a, b = 2} = {a:1};
+ try {
+ eval("let {c = c} = {};");
+ return false;
+ } catch(e){}
+ try {
+ eval("let {c = d, d} = {d:1};");
+ return false;
+ } catch(e){}
+ return a === 1 && b === 2;
+ */
+ },
+ res: {
+ babel6corejs2: babel.optional,
+ closure: true,
+ typescript1corejs2: true,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox47: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ hermes0_12_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'destructuring, assignment',
+ category: 'syntax',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-assignment',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment',
+ subtests: [
+ {
+ name: 'with arrays',
+ exec() {
+ /*
+ var a,b,c;
+ [a, , [b], c] = [5, null, [6]];
+ return a === 5 && b === 6 && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with sparse arrays',
+ exec() {
+ /*
+ var a, b;
+ [a, , b] = [,,,];
+ return a === void undefined && b === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with strings',
+ exec() {
+ /*
+ var a,b,c;
+ [a, b, c] = "ab";
+ return a === "a" && b === "b" && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with astral plane strings',
+ exec() {
+ /*
+ var c;
+ [c] = "𠮷𠮶";
+ return c === "𠮷";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generator instances',
+ exec() {
+ /*
+ var a,b,c;
+ [a, b, c] = (function*(){ yield 1; yield 2; }());
+ return a === 1 && b === 2 && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ safari10: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generic iterables',
+ exec() {
+ /*
+ var a,b,c;
+ [a, b, c] = global.__createIterableObject([1, 2]);
+ return a === 1 && b === 2 && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with instances of generic iterables',
+ exec() {
+ /*
+ var a,b,c;
+ [a, b, c] = Object.create(global.__createIterableObject([1, 2]));
+ return a === 1 && b === 2 && c === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'iterator closing',
+ exec() {
+ /*
+ var closed = false;
+ var iter = global.__createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ var a,b;
+ [a, b] = iter;
+ return closed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ chrome51: true,
+ node6_5: true,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'iterable destructuring expression',
+ exec() {
+ /*
+ var a, b, iterable = [1,2];
+ return ([a, b] = iterable) === iterable;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'chained iterable destructuring',
+ exec() {
+ /*
+ var a,b,c,d;
+ [a,b] = [c,d] = [1,2];
+ return a === 1 && b === 2 && c === 1 && d === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'trailing commas in iterable patterns',
+ exec() {
+ /*
+ var a;
+ [a,] = [1];
+ return a === 1;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with objects',
+ exec() {
+ /*
+ var c,d,e;
+ ({c, x:d, e} = {c:7, x:8});
+ return c === 7 && d === 8 && e === void undefined;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: {
+ val: false,
+ note_id: 'ff11-object-destructuring',
+ note_html:
+ 'Firefox < 16 incorrectly treats ({f,g} = {f:9,g:10})
as assigning to global variables instead of locals.',
+ },
+ firefox15: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'object destructuring with primitives',
+ exec() {
+ /*
+ var toFixed, slice;
+ ({toFixed} = 2);
+ ({slice} = '');
+ return toFixed === Number.prototype.toFixed
+ && slice === String.prototype.slice;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ firefox3_5: false,
+ firefox15: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'trailing commas in object patterns',
+ exec() {
+ /*
+ var a;
+ ({a,} = {a:1});
+ return a === 1;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ firefox4: false,
+ firefox15: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'object destructuring expression',
+ exec() {
+ /*
+ var a, b, obj = { a:1, b:2 };
+ return ({a,b} = obj) === obj;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'parenthesised left-hand-side is a syntax error',
+ exec() {
+ /*
+ var a, b;
+ ({a,b} = {a:1,b:2});
+ try {
+ eval("({a,b}) = {a:3,b:4};");
+ }
+ catch(e) {
+ return a === 1 && b === 2;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ safari7_1: true,
+ firefox2: false,
+ firefox41: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'chained object destructuring',
+ exec() {
+ /*
+ var a,b,c,d;
+ ({a,b} = {c,d} = {a:1,b:2,c:3,d:4});
+ return a === 1 && b === 2 && c === 3 && d === 4;
+ */
+ },
+ res: {
+ tr: true,
+ firefox2: false,
+ firefox3: true,
+ firefox3_5: false,
+ firefox15: true,
+ opera10_50: false,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ safari10: true,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'throws on null and undefined',
+ exec() {
+ /*
+ var a,b;
+ try {
+ ({a} = null);
+ return false;
+ } catch(e) {
+ if (!(e instanceof TypeError))
+ return false;
+ }
+ try {
+ ({b} = void undefined);
+ return false;
+ } catch(e) {
+ if (!(e instanceof TypeError))
+ return false;
+ }
+ return true;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'computed properties',
+ exec() {
+ /*
+ var grault, qux = "corge";
+ ({ [qux]: grault } = { corge: "garply" });
+ return grault === "garply";
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ tr: true,
+ es6tr: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ safari10: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'nested',
+ exec() {
+ /*
+ var e,f,g,h,i;
+ [e, {x:f, g}] = [9, {x:10}];
+ ({h, x:[i]} = {h:11, x:[12]});
+ return e === 9 && f === 10 && g === void undefined
+ && h === 11 && i === 12;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ firefox3_5: false,
+ firefox4: false,
+ firefox15: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'rest',
+ exec() {
+ /*
+ var a,b,c,d;
+ [a, ...b] = [3, 4, 5];
+ [c, ...d] = [6];
+ return a === 3 && b instanceof Array && (b + "") === "4,5" &&
+ c === 6 && d instanceof Array && d.length === 0;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'nested rest',
+ exec() {
+ /*
+ var a = [1, 2, 3], first, last;
+ [first, ...[a[2], last]] = a;
+ return first === 1 && last === 3 && (a + "") === "1,2,2";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox47: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'empty patterns',
+ exec() {
+ /*
+ [] = [1,2];
+ ({} = {a:1,b:2});
+ return true;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'defaults',
+ exec() {
+ /*
+ var a,b,c,d,e,f;
+ ({a = 1, b = 0, z:c = 3} = {b:2, z:undefined});
+ [d = 0, e = 5, f = 6] = [4,,undefined];
+ return a === 1 && b === 2 && c === 3
+ && d === 4 && e === 5 && f === 6;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ closure: true,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox47: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'destructuring, parameters',
+ category: 'syntax',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-destructuring-assignment',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment',
+ subtests: [
+ {
+ name: 'with arrays',
+ exec() {
+ /*
+ return function([a, , [b], c]) {
+ return a === 5 && b === 6 && c === void undefined;
+ }([5, null, [6]]);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with sparse arrays',
+ exec() {
+ /*
+ return function([a, , b]) {
+ return a === void undefined && b === void undefined;
+ }([,,,]);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with strings',
+ exec() {
+ /*
+ return function([a, b, c]) {
+ return a === "a" && b === "b" && c === void undefined;
+ }("ab");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ es6tr: true,
+ jsx: true,
+ ejs: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with astral plane strings',
+ exec() {
+ /*
+ return function([c]) {
+ return c === "𠮷";
+ }("𠮷𠮶");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generator instances',
+ exec() {
+ /*
+ return function([a, b, c]) {
+ return a === 1 && b === 2 && c === void undefined;
+ }(function*(){ yield 1; yield 2; }());
+ */
+ },
+ res: {
+ tr: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ safari5_1: false,
+ safari10: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with generic iterables',
+ exec() {
+ /*
+ return function([a, b, c]) {
+ return a === 1 && b === 2 && c === void undefined;
+ }(global.__createIterableObject([1, 2]));
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'with instances of generic iterables',
+ exec() {
+ /*
+ return function([a, b, c]) {
+ return a === 1 && b === 2 && c === void undefined;
+ }(Object.create(global.__createIterableObject([1, 2])));
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ typescript1corejs2: typescript.downlevelIteration,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'iterator closing',
+ exec() {
+ /*
+ var closed = false;
+ var iter = global.__createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ (function([a,b]) {}(iter));
+ return closed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.downlevelIteration,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome51: true,
+ node6_5: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'trailing commas in iterable patterns',
+ exec() {
+ /*
+ return function([a,]) {
+ return a === 1;
+ }([1]);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'with objects',
+ exec() {
+ /*
+ return function({c, x:d, e}) {
+ return c === 7 && d === 8 && e === void undefined;
+ }({c:7, x:8});
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: {
+ val: true,
+ note_id: 'ff11-object-destructuring',
+ note_html:
+ 'Firefox < 16 incorrectly treats ({f,g} = {f:9,g:10})
as assigning to global variables instead of locals.',
+ },
+ firefox16: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'object destructuring with primitives',
+ exec() {
+ /*
+ return function({toFixed}, {slice}) {
+ return toFixed === Number.prototype.toFixed
+ && slice === String.prototype.slice;
+ }(2,'');
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'trailing commas in object patterns',
+ exec() {
+ /*
+ return function({a,}) {
+ return a === 1;
+ }({a:1});
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'throws on null and undefined',
+ exec() {
+ /*
+ try {
+ (function({a}){}(null));
+ return false;
+ } catch(e) {}
+ try {
+ (function({b}){}(undefined));
+ return false;
+ } catch(e) {}
+ return true;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'computed properties',
+ exec() {
+ /*
+ var qux = "corge";
+ return function({ [qux]: grault }) {
+ return grault === "garply";
+ }({ corge: "garply" });
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ closure: true,
+ tr: true,
+ es6tr: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ safari10: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'nested',
+ exec() {
+ /*
+ return function([e, {x:f, g}], {h, x:[i]}) {
+ return e === 9 && f === 10 && g === void undefined
+ && h === 11 && i === 12;
+ }([9, {x:10}],{h:11, x:[12]});
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: "'arguments' interaction",
+ exec() {
+ /*
+ return (function({a, x:b, y:e}, [c, d]) {
+ return arguments[0].a === 1 && arguments[0].x === 2
+ && !("y" in arguments[0]) && arguments[1] + '' === "3,4";
+ }({a:1, x:2}, [3, 4]));
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ jxa: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'new Function() support',
+ exec() {
+ /*
+ return new Function("{a, x:b, y:e}","[c, d]",
+ "return a === 1 && b === 2 && c === 3 && "
+ + "d === 4 && e === void undefined;"
+ )({a:1, x:2}, [3, 4]);
+ */
+ },
+ res: {
+ safari7_1: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: "in parameters, function 'length' property",
+ exec() {
+ /*
+ return function({a, b}, [c, d]){}.length === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ firefox2: false,
+ firefox3: true,
+ opera10_50: false,
+ safari7_1: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'rest',
+ exec() {
+ /*
+ return function([a, ...b], [c, ...d]) {
+ return a === 3 && b instanceof Array && (b + "") === "4,5" &&
+ c === 6 && d instanceof Array && d.length === 0;
+ }([3, 4, 5], [6]);
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'empty patterns',
+ exec() {
+ /*
+ return function ([],{}){
+ return arguments[0] + '' === "3,4" && arguments[1].x === "foo";
+ }([3,4],{x:"foo"});
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ es6tr: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ opera10_50: false,
+ safari9: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'defaults',
+ exec() {
+ /*
+ return (function({a = 1, b = 0, c = 3, x:d = 0, y:e = 5},
+ [f = 6, g = 0, h = 8]) {
+ return a === 1 && b === 2 && c === 3 && d === 4 &&
+ e === 5 && f === 6 && g === 7 && h === 8;
+ }({b:2, c:undefined, x:4},[, 7, undefined]));
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: true,
+ es6tr: true,
+ closure: true,
+ safari10: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox47: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'defaults, separate scope',
+ exec() {
+ /*
+ return (function({a=function(){
+ return typeof b === 'undefined';
+ }}){
+ var b = 1;
+ return a();
+ }({}));
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ closure: true,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'defaults, new Function() support',
+ exec() {
+ /*
+ return new Function("{a = 1, b = 0, c = 3, x:d = 0, y:e = 5}",
+ "return a === 1 && b === 2 && c === 3 && d === 4 && e === 5;"
+ )({b:2, c:undefined, x:4});
+ */
+ },
+ res: {
+ safari10: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge13: edge.experimental,
+ edge14: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: { val: false, note_id: 'ejs-no-function-ctor' },
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'aliased defaults, arrow function',
+ exec() {
+ /*
+ return ((a, {b: x = 0, c: y = 3}) => {
+ return a === 1 && x === 2 && y === 3;
+ })(1, {b: 2});
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ tr: true,
+ ie11: false,
+ edge12: false,
+ edge15: true,
+ chrome47: chrome.experimental,
+ chrome49: true,
+ firefox50: false,
+ firefox52: true,
+ opera10_50: false,
+ node6: true,
+ node6_5: true,
+ node8: true,
+ safari9: false,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'shorthand defaults, arrow function',
+ exec() {
+ /*
+ return ((a, {b = 0, c = 3}) => {
+ return a === 1 && b === 2 && c === 3;
+ })(1, {b: 2});
+ */
+ },
+ res: {
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ tr: true,
+ ie11: false,
+ edge15: false,
+ edge18: true,
+ chrome47: chrome.experimental,
+ chrome49: true,
+ firefox50: false,
+ firefox52: true,
+ opera10_50: false,
+ node6: true,
+ node6_5: true,
+ node8: true,
+ safari9: false,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'duplicate identifier',
+ exec() {
+ /*
+ try {
+ eval('var d = function d([d]) { return d };');
+ if (d([true]) !== true) return false;
+ } catch (e) {
+ return !(e instanceof SyntaxError);
+ }
+
+ try {
+ eval('var f = function f([id, id]) { return id }');
+ return false;
+ } catch (e) {
+ return e instanceof SyntaxError;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ es6tr: true,
+ jsx: true,
+ closure: true,
+ typescript1corejs2: true,
+ firefox2: true,
+ safari11: false,
+ safari16_2: false,
+ safari16_3: true,
+ edge13: edge.experimental,
+ edge14: true,
+ xs6: true,
+ chrome49: true,
+ node6: true,
+ node6_5: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Promise',
+ category: 'built-ins',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-promise-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise',
+ subtests: [
+ {
+ name: 'basic functionality',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise',
+ exec() {
+ /*
+ var p1 = new Promise(function(resolve, reject) { resolve("foo"); });
+ var p2 = new Promise(function(resolve, reject) { reject("quux"); });
+ var score = 0;
+
+ function thenFn(result) { score += (result === "foo"); check(); }
+ function catchFn(result) { score += (result === "quux"); check(); }
+ function shouldNotRun(result) { score = -Infinity; }
+
+ p1.then(thenFn, shouldNotRun);
+ p2.then(shouldNotRun, catchFn);
+ p1.catch(shouldNotRun);
+ p2.catch(catchFn);
+
+ p1.then(function() {
+ // Promise.prototype.then() should return a new Promise
+ score += p1.then() !== p1;
+ check();
+ });
+
+ function check() {
+ if (score === 4) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ opera10_50: false,
+ chrome33: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'constructor requires new',
+ exec() {
+ /*
+ new Promise(function(){});
+ try {
+ Promise(function(){});
+ return false;
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ firefox2: false,
+ firefox30: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ chrome33: true,
+ node4: true,
+ safari10: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: "Promise.prototype isn't an instance",
+ exec() {
+ /*
+ new Promise(function(){});
+ try {
+ Promise.prototype.then(function(){});
+ } catch (e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ firefox31: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome33: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Promise.all',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/all',
+ exec() {
+ /*
+ var fulfills = Promise.all([
+ new Promise(function(resolve) { setTimeout(resolve,2000,"foo"); }),
+ new Promise(function(resolve) { setTimeout(resolve,1000,"bar"); })
+ ]);
+ var rejects = Promise.all([
+ new Promise(function(_, reject) { setTimeout(reject, 2000,"baz"); }),
+ new Promise(function(_, reject) { setTimeout(reject, 1000,"qux"); })
+ ]);
+ var score = 0;
+ fulfills.then(function(result) { score += (result + "" === "foo,bar"); check(); });
+ rejects.catch(function(result) { score += (result === "qux"); check(); });
+
+ function check() {
+ if (score === 2) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ opera10_50: false,
+ chrome33: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Promise.all, generic iterables',
+ exec() {
+ /*
+ var fulfills = Promise.all(global.__createIterableObject([
+ new Promise(function(resolve) { setTimeout(resolve,2000,"foo"); }),
+ new Promise(function(resolve) { setTimeout(resolve,1000,"bar"); })
+ ]));
+ var rejects = Promise.all(global.__createIterableObject([
+ new Promise(function(_, reject) { setTimeout(reject, 2000,"baz"); }),
+ new Promise(function(_, reject) { setTimeout(reject, 1000,"qux"); })
+ ]));
+ var score = 0;
+ fulfills.then(function(result) { score += (result + "" === "foo,bar"); check(); });
+ rejects.catch(function(result) { score += (result === "qux"); check(); });
+
+ function check() {
+ if (score === 2) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ es6shim: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome43: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Promise.race',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise/race',
+ exec() {
+ /*
+ var fulfills = Promise.race([
+ new Promise(function(resolve) { setTimeout(resolve,1000,"foo"); }),
+ new Promise(function(_, reject) { setTimeout(reject, 2000,"bar"); })
+ ]);
+ var rejects = Promise.race([
+ new Promise(function(_, reject) { setTimeout(reject, 1000,"baz"); }),
+ new Promise(function(resolve) { setTimeout(resolve,2000,"qux"); })
+ ]);
+ var score = 0;
+ fulfills.then(function(result) { score += (result === "foo"); check(); });
+ rejects.catch(function(result) { score += (result === "baz"); check(); });
+
+ function check() {
+ if (score === 2) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ opera10_50: false,
+ chrome33: true,
+ safari10: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Promise.race, generic iterables',
+ exec() {
+ /*
+ var fulfills = Promise.race(global.__createIterableObject([
+ new Promise(function(resolve) { setTimeout(resolve,1000,"foo"); }),
+ new Promise(function(_, reject) { setTimeout(reject, 2000,"bar"); })
+ ]));
+ var rejects = Promise.race(global.__createIterableObject([
+ new Promise(function(_, reject) { setTimeout(reject, 1000,"baz"); }),
+ new Promise(function(resolve) { setTimeout(resolve,2000,"qux"); })
+ ]));
+ var score = 0;
+ fulfills.then(function(result) { score += (result === "foo"); check(); });
+ rejects.catch(function(result) { score += (result === "baz"); check(); });
+
+ function check() {
+ if (score === 2) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ es6shim: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome43: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Promise[Symbol.species]',
+ exec() {
+ /*
+ var prop = Object.getOwnPropertyDescriptor(Promise, Symbol.species);
+ return 'get' in prop && Promise[Symbol.species] === Promise;
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Object static methods',
+ category: 'built-in extensions',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-object-constructor',
+ subtests: [
+ {
+ name: 'Object.assign',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign',
+ exec() {
+ /*
+ var o = Object.assign({a:true}, {b:true}, {c:true});
+ return "a" in o && "b" in o && "c" in o;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.is',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/is',
+ exec() {
+ /*
+ return typeof Object.is === 'function' &&
+ Object.is(NaN, NaN) &&
+ !Object.is(-0, 0);
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ es6shim: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox22: true,
+ opera10_50: false,
+ chrome19: true,
+ safari9: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_1: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.getOwnPropertySymbols',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertySymbols',
+ exec() {
+ /*
+ var o = {};
+ var sym = Symbol(), sym2 = Symbol(), sym3 = Symbol();
+ o[sym] = true;
+ o[sym2] = true;
+ o[sym3] = true;
+ var result = Object.getOwnPropertySymbols(o);
+ return result[0] === sym
+ && result[1] === sym2
+ && result[2] === sym3;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ tr: true,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.setPrototypeOf',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/setPrototypeOf',
+ exec() {
+ /*
+ return Object.setPrototypeOf({}, Array.prototype) instanceof Array;
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: { val: false, note_id: 'compiler-proto' },
+ closure: { val: false, note_id: 'compiler-proto' },
+ typescript1corejs2: { val: false, note_id: 'compiler-proto' },
+ es6shim: { val: false, note_id: 'compiler-proto' },
+ ie11: true,
+ firefox2: false,
+ firefox31: true,
+ opera10_50: false,
+ chrome34: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Object static methods accept primitives',
+ category: 'misc',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-object-constructor',
+ subtests: [
+ {
+ name: 'Object.getPrototypeOf',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getPrototypeOf',
+ exec() {
+ /*
+ return Object.getPrototypeOf('a').constructor === String;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox3_5: true,
+ firefox4: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.getOwnPropertyDescriptor',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyDescriptor',
+ exec() {
+ /*
+ return Object.getOwnPropertyDescriptor('a', 'foo') === void undefined;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.getOwnPropertyNames',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/getOwnPropertyNames',
+ exec() {
+ /*
+ var s = Object.getOwnPropertyNames('a');
+ return s.length === 2 &&
+ ((s[0] === 'length' && s[1] === '0') || (s[0] === '0' && s[1] === 'length'));
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox33: true,
+ opera10_50: false,
+ chrome40: true,
+ node4: true,
+ es6shim: true,
+ safari9: true,
+ chrome44: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.seal',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/seal',
+ exec() {
+ /*
+ return Object.seal('a') === 'a';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.freeze',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze',
+ exec() {
+ /*
+ return Object.freeze('a') === 'a';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.preventExtensions',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/preventExtensions',
+ exec() {
+ /*
+ return Object.preventExtensions('a') === 'a';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.isSealed',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isSealed',
+ exec() {
+ /*
+ return Object.isSealed('a') === true;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.isFrozen',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isFrozen',
+ exec() {
+ /*
+ return Object.isFrozen('a') === true;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.isExtensible',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/isExtensible',
+ exec() {
+ /*
+ return Object.isExtensible('a') === false;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ safari9: true,
+ chrome44: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.keys',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys',
+ exec() {
+ /*
+ var s = Object.keys('a');
+ return s.length === 1 && s[0] === '0';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox35: true,
+ opera10_50: false,
+ chrome40: true,
+ safari9: true,
+ node4: true,
+ chrome44: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Object.prototype.__proto__',
+ category: 'annex b',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-object.prototype.__proto__',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto',
+ subtests: [
+ {
+ name: 'get prototype',
+ exec() {
+ /*
+ var A = function(){};
+ return (new A()).__proto__ === A.prototype;
+ */
+ },
+ res: {
+ ie11: true,
+ firefox2: true,
+ chrome5: true,
+ deno1_0: false,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape1_0: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'set prototype',
+ exec() {
+ /*
+ var o = {};
+ o.__proto__ = Array.prototype;
+ return o instanceof Array;
+ */
+ },
+ res: {
+ ie11: true,
+ firefox2: true,
+ chrome5: true,
+ deno1_0: false,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'absent from Object.create(null)',
+ exec() {
+ /*
+ var o = Object.create(null), p = {};
+ o.__proto__ = p;
+ return Object.getPrototypeOf(o) !== p;
+ */
+ },
+ res: {
+ ie11: true,
+ firefox2: false,
+ firefox4: true,
+ chrome30: true,
+ safari6: true,
+ opera10_50: false,
+ opera12_10: true,
+ node0_12: true,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'present in hasOwnProperty()',
+ exec() {
+ /*
+ return Object.prototype.hasOwnProperty('__proto__');
+ */
+ },
+ res: {
+ konq4_14: true,
+ ie11: true,
+ firefox2: true,
+ chrome30: true,
+ deno1_0: false,
+ safari3_1: true,
+ opera10_50: false,
+ opera12_10: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ android4_0: true,
+ android4_1: false,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'correct property descriptor',
+ exec() {
+ /*
+ var desc = Object.getOwnPropertyDescriptor(Object.prototype,"__proto__");
+ var A = function(){};
+
+ return (desc
+ && "get" in desc
+ && "set" in desc
+ && desc.configurable
+ && !desc.enumerable);
+ */
+ },
+ res: {
+ ie11: true,
+ firefox2: false,
+ firefox17: true,
+ chrome30: true,
+ deno1_0: false,
+ safari6: true,
+ opera10_50: false,
+ opera12_10: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'present in Object.getOwnPropertyNames()',
+ exec() {
+ /*
+ return Object.getOwnPropertyNames(Object.prototype).indexOf('__proto__') > -1;
+ */
+ },
+ res: {
+ ie11: true,
+ firefox2: false,
+ firefox7: true,
+ firefox10: false,
+ firefox39: true,
+ chrome30: true,
+ deno1_0: false,
+ safari6: true,
+ opera10_50: false,
+ opera12_10: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'function "name" property',
+ category: 'built-in extensions',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-setfunctionname',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function/name',
+ subtests: [
+ {
+ name: 'function statements',
+ exec() {
+ /*
+ function foo(){};
+ return foo.name === 'foo' &&
+ (function(){}).name === '';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ firefox2: true,
+ chrome5: true,
+ safari4: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ ie11: false,
+ edge12: true,
+ edge13: false,
+ edge14: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'function expressions',
+ exec() {
+ /*
+ return (function foo(){}).name === 'foo' &&
+ (function(){}).name === '';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ firefox2: true,
+ chrome5: true,
+ safari4: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ ie11: false,
+ edge12: true,
+ edge13: false,
+ edge14: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'new Function',
+ exec() {
+ /*
+ return (new Function).name === "anonymous";
+ */
+ },
+ res: {
+ firefox2: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ safari4: true,
+ konq4_14: true,
+ android4_0: true,
+ android4_1: false,
+ chrome48: true,
+ node6: true,
+ node6_5: true,
+ xs6: true,
+ ejs: { val: false, note_id: 'ejs-no-function-ctor' },
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'bound functions',
+ exec() {
+ /*
+ function foo() {};
+ return foo.bind({}).name === "bound foo" &&
+ (function(){}).bind({}).name === "bound ";
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox47: true,
+ opera10_50: false,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'variables (function)',
+ exec() {
+ /*
+ var foo = function() {};
+ var bar = function baz() {};
+ return foo.name === "foo" && bar.name === "baz";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: edge.experimental,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ node6_5: true,
+ babel6corejs2: babel.corejs,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'object methods (function)',
+ exec() {
+ /*
+ var o = { foo: function(){}, bar: function baz(){}};
+ o.qux = function(){};
+ return o.foo.name === "foo" &&
+ o.bar.name === "baz" &&
+ o.qux.name === "";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ node6_5: true,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'accessor properties',
+ exec() {
+ /*
+ var o = { get foo(){}, set foo(x){} };
+ var descriptor = Object.getOwnPropertyDescriptor(o, "foo");
+ return descriptor.get.name === "get foo" &&
+ descriptor.set.name === "set foo";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ node6_5: true,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'shorthand methods',
+ exec() {
+ /*
+ var o = { foo(){} };
+ return o.foo.name === "foo";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ chrome41: chrome.experimental,
+ chrome42: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'shorthand methods (no lexical binding)',
+ exec() {
+ /*
+ var f = "foo";
+ return ({f() { return f; }}).f() === "foo";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ chrome41: chrome.experimental,
+ chrome42: true,
+ node4: true,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'symbol-keyed methods',
+ exec() {
+ /*
+ var sym1 = Symbol("foo");
+ var sym2 = Symbol();
+ var o = {
+ [sym1]: function(){},
+ [sym2]: function(){}
+ };
+
+ return o[sym1].name === "[foo]" &&
+ o[sym2].name === "";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ node6_5: true,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'class statements',
+ exec() {
+ /*
+ class foo {};
+ class bar { static name() {} };
+ return foo.name === "foo" &&
+ typeof bar.name === "function";
+ */
+ },
+ res: {
+ babel6corejs2: {
+ val: false,
+ note_id: 'name-configurable',
+ note_html: 'Requires function "name"
properties to be natively configurable',
+ },
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'class expressions',
+ exec() {
+ /*
+ return class foo {}.name === "foo" &&
+ typeof class bar { static name() {} }.name === "function";
+ */
+ },
+ res: {
+ babel6corejs2: { val: false, note_id: 'name-configurable' },
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'variables (class)',
+ exec() {
+ /*
+ var foo = class {};
+ var bar = class baz {};
+ var qux = class { static name() {} };
+ return foo.name === "foo" &&
+ bar.name === "baz" &&
+ typeof qux.name === "function";
+ */
+ },
+ res: {
+ babel6corejs2: { val: false, note_id: 'name-configurable' },
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ node6_5: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'object methods (class)',
+ exec() {
+ /*
+ var o = { foo: class {}, bar: class baz {}};
+ o.qux = class {};
+ return o.foo.name === "foo" &&
+ o.bar.name === "baz" &&
+ o.qux.name === "";
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ node6_5: true,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'class prototype methods',
+ exec() {
+ /*
+ class C { foo(){} };
+ return (new C).foo.name === "foo";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ edge14: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'class static methods',
+ exec() {
+ /*
+ class C { static foo(){} };
+ return C.foo.name === "foo";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari9: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: "isn't writable, is configurable",
+ exec() {
+ /*
+ var descriptor = Object.getOwnPropertyDescriptor(function f(){},"name");
+ return descriptor.enumerable === false &&
+ descriptor.writable === false &&
+ descriptor.configurable === true;
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox38: true,
+ opera10_50: false,
+ chrome43: true,
+ node4: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'String static methods',
+ category: 'built-in extensions',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-string-constructor',
+ subtests: [
+ {
+ name: 'String.raw',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/raw',
+ exec() {
+ /*
+ return typeof String.raw === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure20211006: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome41: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'String.fromCodePoint',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/fromCodePoint',
+ exec() {
+ /*
+ return typeof String.fromCodePoint === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ opera10_50: false,
+ chrome38: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'String.prototype methods',
+ category: 'built-in extensions',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-string-prototype-object',
+ subtests: [
+ {
+ name: 'String.prototype.codePointAt',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/codePointAt',
+ exec() {
+ /*
+ return typeof String.prototype.codePointAt === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ opera10_50: false,
+ chrome38: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.normalize',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/normalize',
+ exec() {
+ /*
+ return typeof String.prototype.normalize === "function"
+ && "c\u0327\u0301".normalize("NFC") === "\u1e09"
+ && "\u1e09".normalize("NFD") === "c\u0327\u0301";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox31: true,
+ opera10_50: false,
+ chrome34: true,
+ chrome41: true,
+ node4: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.repeat',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/repeat',
+ exec() {
+ /*
+ return typeof String.prototype.repeat === 'function'
+ && "foo".repeat(3) === "foofoofoo";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox24: true,
+ opera10_50: false,
+ safari9: true,
+ chrome30: chrome.experimental,
+ chrome41: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.startsWith',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/startsWith',
+ exec() {
+ /*
+ return typeof String.prototype.startsWith === 'function'
+ && "foobar".startsWith("foo");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox17: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_1: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.startsWith throws on RegExp',
+ exec() {
+ /*
+ try {
+ "a".startsWith(/./);
+ } catch(e) {
+ return typeof String.prototype.startsWith === 'function';
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox17: false,
+ firefox29: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_1: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.endsWith',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith',
+ exec() {
+ /*
+ return typeof String.prototype.endsWith === 'function'
+ && "foobar".endsWith("bar");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox17: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_1: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.endsWith throws on RegExp',
+ exec() {
+ /*
+ try {
+ "a".endsWith(/./);
+ } catch(e) {
+ return typeof String.prototype.endsWith === 'function';
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox29: true,
+ opera10_50: false,
+ chrome30: false,
+ chrome34: chrome.experimental,
+ chrome41: true,
+ safari9: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_1: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype.includes',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/includes',
+ exec() {
+ /*
+ return typeof String.prototype.includes === 'function'
+ && "foobar".includes("oba");
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ firefox2: false,
+ firefox18: {
+ val: false,
+ note_id: 'string-contains',
+ note_html: 'Available as the draft standard String.prototype.contains
',
+ },
+ firefox40: true,
+ opera10_50: false,
+ chrome30: { val: false, note_id: 'string-contains' },
+ chrome41: true,
+ safari9: true,
+ node0_12: { val: 'flagged', note_id: 'string-contains' },
+ node4: true,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_1: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String.prototype[Symbol.iterator]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/@@iterator',
+ exec() {
+ /*
+ return typeof String.prototype[Symbol.iterator] === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome37: chrome.experimental,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'String iterator prototype chain',
+ exec() {
+ /*
+ // Iterator instance
+ var iterator = ''[Symbol.iterator]();
+ // %StringIteratorPrototype%
+ var proto1 = Object.getPrototypeOf(iterator);
+ // %IteratorPrototype%
+ var proto2 = Object.getPrototypeOf(proto1);
+
+ return proto2.hasOwnProperty(Symbol.iterator) &&
+ !proto1 .hasOwnProperty(Symbol.iterator) &&
+ !iterator .hasOwnProperty(Symbol.iterator) &&
+ iterator[Symbol.iterator]() === iterator;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'String.prototype HTML methods',
+ category: 'annex b',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-string.prototype.anchor',
+ subtests: [
+ {
+ name: 'existence',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/prototype#HTML_wrapper_methods',
+ exec() {
+ /*
+ var i, names = ["anchor", "big", "bold", "fixed", "fontcolor", "fontsize",
+ "italics", "link", "small", "strike", "sub", "sup"];
+ for (i = 0; i < names.length; i++) {
+ if (typeof String.prototype[names[i]] !== 'function') {
+ return false;
+ }
+ }
+ return true;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie10: true,
+ firefox2: false,
+ firefox3: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: false,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ {
+ name: "tags' names are lowercase",
+ exec() {
+ /*
+ var i, names = ["anchor", "big", "bold", "fixed", "fontcolor", "fontsize",
+ "italics", "link", "small", "strike", "sub", "sup"];
+ for (i = 0; i < names.length; i++) {
+ if (""[names[i]]().toLowerCase() !== ""[names[i]]()) {
+ return false;
+ }
+ }
+ return true;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: false,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ {
+ name: 'quotes in arguments are escaped',
+ exec() {
+ /*
+ var i, names = ["anchor", "fontcolor", "fontsize", "link"];
+ for (i = 0; i < names.length; i++) {
+ if (""[names[i]]('"') !== ""[names[i]]('&' + 'quot;')) {
+ return false;
+ }
+ }
+ return true;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox17: true,
+ opera10_50: false,
+ chrome5: true,
+ safari6: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: false,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Unicode code point escapes',
+ category: 'syntax',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-literals-string-literals',
+ subtests: [
+ {
+ name: 'in strings',
+ exec() {
+ /*
+ return '\u{1d306}' === '\ud834\udf06';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ typescript1corejs2: true,
+ es6tr: true,
+ ejs: true,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ safari9: true,
+ chrome44: true,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'in identifiers',
+ exec() {
+ /*
+ var \u{102C0} = 2;
+ return \u{102C0} === 2;
+ */
+ },
+ res: {
+ closure20200517: true,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ chrome44: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_4_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'in property key definitions',
+ exec() {
+ /*
+ var o = { \u{102C0} : 2 };
+ return o['\ud800\udec0'] === 2;
+ */
+ },
+ res: {
+ closure20200517: false,
+ ejs: true,
+ edge12: true,
+ chrome44: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_4_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'in property key accesses',
+ exec() {
+ /*
+ var o = { '\ud800\udec0' : 2 };
+ return o.\u{102C0} === 2;
+ */
+ },
+ res: {
+ closure20200517: false,
+ edge12: true,
+ chrome44: true,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ safari9: true,
+ node4: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_4_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'new.target',
+ category: 'syntax',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-built-in-function-objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new.target',
+ subtests: [
+ {
+ name: 'in constructors',
+ exec() {
+ /*
+ var passed = false;
+ new function f() {
+ passed = (new.target === f);
+ }();
+ (function() {
+ passed &= (new.target === void undefined);
+ }());
+ return passed;
+ */
+ },
+ res: {
+ closure: false,
+ closure20200517: true,
+ firefox2: false,
+ firefox41: true,
+ opera10_50: false,
+ safari10: true,
+ chrome46: true,
+ ie11: false,
+ edge13: true,
+ node5: true,
+ xs6: true,
+ ejs: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'assignment is an early error',
+ exec() {
+ /*
+ var passed = false;
+ new function f() {
+ passed = (new.target === f);
+ }();
+
+ try {
+ Function("new.target = function(){};");
+ } catch(e) {
+ return passed;
+ }
+ */
+ },
+ res: {
+ babel7corejs2: true,
+ closure: false,
+ closure20200517: true,
+ firefox2: false,
+ firefox41: true,
+ opera10_50: false,
+ chrome46: true,
+ ie11: false,
+ edge14: true,
+ node5: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Symbol',
+ category: 'built-ins',
+ significance: 'large',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-symbol-constructor',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ var object = {};
+ var symbol = Symbol();
+ var value = {};
+ object[symbol] = value;
+ return object[symbol] === value;
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome30: chrome.experimental, // Actually Chrome 29
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'typeof support',
+ exec() {
+ /*
+ return typeof Symbol() === "symbol";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome30: chrome.experimental, // Actually Chrome 29
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'symbol keys are hidden to pre-ES6 code',
+ exec() {
+ /*
+ var object = {};
+ var symbol = Symbol();
+ object[symbol] = 1;
+
+ for (var x in object){}
+ var passed = !x;
+
+ if (Object.keys && Object.getOwnPropertyNames) {
+ passed &= Object.keys(object).length === 0
+ && Object.getOwnPropertyNames(object).length === 0;
+ }
+
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome30: chrome.experimental, // Actually Chrome 29
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object.defineProperty support',
+ exec() {
+ /*
+ var object = {};
+ var symbol = Symbol();
+ var value = {};
+
+ if (Object.defineProperty) {
+ Object.defineProperty(object, symbol, { value: value });
+ return object[symbol] === value;
+ }
+
+ return passed;
+ */
+ },
+ res: {
+ tr: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome30: chrome.experimental, // Actually Chrome 29
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'symbols inherit from Symbol.prototype',
+ exec() {
+ /*
+ var symbol = Symbol();
+ var passed = symbol.foo === void undefined;
+ Symbol.prototype.foo = 2;
+ passed &= symbol.foo === 2;
+ delete Symbol.prototype.foo;
+ return passed;
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome30: chrome.experimental, // Actually Chrome 29
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'cannot coerce to string or number',
+ exec() {
+ /*
+ var symbol = Symbol();
+
+ try {
+ symbol + "";
+ return false;
+ }
+ catch(e) {}
+
+ try {
+ symbol + 0;
+ return false;
+ } catch(e) {}
+
+ return true;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'can convert with String()',
+ exec() {
+ /*
+ return String(Symbol("foo")) === "Symbol(foo)";
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ chrome39: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'new Symbol() throws',
+ exec() {
+ /*
+ var symbol = Symbol();
+ try {
+ new Symbol();
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure20190301: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome35: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Object(symbol)',
+ exec() {
+ /*
+ var symbol = Symbol();
+ var symbolObject = Object(symbol);
+
+ return typeof symbolObject === "object" &&
+ symbolObject instanceof Symbol &&
+ symbolObject == symbol && // eslint-disable-line eqeqeq
+ symbolObject !== symbol &&
+ symbolObject.valueOf() === symbol;
+ */
+ },
+ res: {
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome35: false,
+ chrome48: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_1: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'JSON.stringify ignores symbol primitives',
+ exec() {
+ /*
+ var object = { foo: Symbol() };
+ object[Symbol()] = 1;
+ var array = [Symbol()];
+ return JSON.stringify(object) === '{}' && JSON.stringify(array) === '[null]' && JSON.stringify(Symbol()) === void undefined;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge13: true,
+ es6shim: true,
+ firefox2: false,
+ firefox35: false,
+ firefox36: true,
+ firefox48: true,
+ opera10_50: false,
+ chrome35: chrome.experimental,
+ chrome38: true,
+ chrome49: true,
+ chrome52: true,
+ node0_12: true,
+ node4: true,
+ node6: true,
+ safari9: false,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'JSON.stringify ignores symbol objects',
+ exec() {
+ /*
+ var testSymbolObject = function (sym) {
+ var object = { foo: sym };
+ try {
+ // some browsers throw a TypeError when setting symbol object keys.
+ // this isn't part of this test, so, ignore it if so.
+ object[sym] = 1;
+ } catch (e) {} // some browsers throw a TypeError when setting symbol object keys.
+ var array = [sym];
+ return JSON.stringify(object) === '{"foo":{}}' && JSON.stringify(array) === '[{}]' && JSON.stringify(sym) === '{}';
+ };
+ var objSym = Object(Symbol());
+ var symNoToJSON = Object(Symbol());
+ Object.defineProperty(symNoToJSON, 'toJSON', { enumerable: false, value: null }); // ensure it overrides the prototype, but is not callable
+ return testSymbolObject(objSym) && testSymbolObject(symNoToJSON);
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge13: true,
+ es6shim: true,
+ firefox2: false,
+ firefox35: false,
+ firefox36: true,
+ firefox48: true,
+ opera10_50: false,
+ node0_12: false,
+ node4: false,
+ node6: true,
+ chrome38: false,
+ chrome48: false,
+ chrome49: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'global symbol registry',
+ exec() {
+ /*
+ var symbol = Symbol.for('foo');
+ return Symbol.for('foo') === symbol &&
+ Symbol.keyFor(symbol) === 'foo';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome35: chrome.experimental,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'well-known symbols',
+ category: 'built-ins',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-well-known-symbols',
+ note_id: 'symbol-iterator-functionality',
+ note_html:
+ 'Functionality for Symbol.iterator
is tested by the "generic iterators" subtests for ' +
+ 'the spread (...) operator, for..of loops, ' +
+ 'destructuring, yield *, ' +
+ 'and Array.from.',
+ subtests: [
+ {
+ name: 'Symbol.hasInstance',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance',
+ exec() {
+ /*
+ var passed = false;
+ var obj = { foo: true };
+ var C = function(){};
+ Object.defineProperty(C, Symbol.hasInstance, {
+ value: function(inst) { passed = inst.foo; return false; }
+ });
+ obj instanceof C;
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.optional,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge15: true,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ firefox2: false,
+ firefox50: true,
+ opera10_50: false,
+ ejs: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.isConcatSpreadable, non-spreadable array',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable',
+ exec() {
+ /*
+ var a = [], b = [];
+ b[Symbol.isConcatSpreadable] = false;
+ a = a.concat(b);
+ return a[0] === b;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ ejs: true,
+ chrome48: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Symbol.isConcatSpreadable, spreadable object with poisoned getter',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable',
+ exec() {
+ /*
+ if (typeof Symbol !== 'function' || !Symbol.isConcatSpreadable) {
+ return null;
+ }
+ var spreadableHasPoisonedIndex = { length: Math.pow(2, 53) - 1 };
+ spreadableHasPoisonedIndex[Symbol.isConcatSpreadable] = true;
+ Object.defineProperty(spreadableHasPoisonedIndex, 0, {
+ get: function () { throw new SyntaxError(); }
+ });
+ try {
+ [].concat(spreadableHasPoisonedIndex);
+ return false;
+ } catch (e) {
+ return !!e && e.name === 'SyntaxError';
+ }
+ */
+ },
+ res: {
+ chrome48: false,
+ chrome100: false,
+ chrome101: false,
+ safari5_1: false,
+ safari9: false,
+ safari12_1: false,
+ safari13: false,
+ safari14: true,
+ safari15: true,
+ firefox48: true,
+ firefox60: true,
+ firefox70: true,
+ firefox99: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Symbol.iterator, existence',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator',
+ exec() {
+ /*
+ return "iterator" in Symbol;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ edge14: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome37: chrome.experimental,
+ chrome38: true,
+ ejs: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Symbol.iterator, arguments object',
+ exec() {
+ /*
+ return (function() {
+ return typeof arguments[Symbol.iterator] === 'function'
+ && Object.hasOwnProperty.call(arguments, Symbol.iterator);
+ }());
+ */
+ },
+ res: {
+ chrome37: chrome.experimental,
+ chrome38: true,
+ safari9: true,
+ firefox2: false,
+ firefox46: true,
+ opera10_50: false,
+ node0_12: false,
+ node4: true,
+ node5: true,
+ ie11: false,
+ edge12: true,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Symbol.species, existence',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/species',
+ exec() {
+ /*
+ return "species" in Symbol;
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ firefox2: false,
+ firefox41: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Symbol.species, Array.prototype.concat',
+ exec() {
+ /*
+ var obj = [];
+ obj.constructor = {};
+ obj.constructor[Symbol.species] = function() {
+ return { foo: 1 };
+ };
+ return Array.prototype.concat.call(obj, []).foo === 1;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.species, Array.prototype.filter',
+ exec() {
+ /*
+ var obj = [];
+ obj.constructor = {};
+ obj.constructor[Symbol.species] = function() {
+ return { foo: 1 };
+ };
+ return Array.prototype.filter.call(obj, Boolean).foo === 1;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.species, Array.prototype.map',
+ exec() {
+ /*
+ var obj = [];
+ obj.constructor = {};
+ obj.constructor[Symbol.species] = function() {
+ return { foo: 1 };
+ };
+ return Array.prototype.map.call(obj, Boolean).foo === 1;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.species, Array.prototype.slice',
+ exec() {
+ /*
+ var obj = [];
+ obj.constructor = {};
+ obj.constructor[Symbol.species] = function() {
+ return { foo: 1 };
+ };
+ return Array.prototype.slice.call(obj, 0).foo === 1;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.species, Array.prototype.splice',
+ exec() {
+ /*
+ var obj = [];
+ obj.constructor = {};
+ obj.constructor[Symbol.species] = function() {
+ return { foo: 1 };
+ };
+ return Array.prototype.splice.call(obj, 0).foo === 1;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.species, RegExp.prototype[Symbol.split]',
+ exec() {
+ /*
+ var passed = false;
+ var obj = { constructor: {} };
+ obj[Symbol.split] = RegExp.prototype[Symbol.split];
+ obj.constructor[Symbol.species] = function() {
+ passed = true;
+ return /./;
+ };
+ "".split(obj);
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: false,
+ babel7corejs3: babel.corejs,
+ typescript1corejs2: typescript.fallthrough,
+ typescript3_2corejs3: typescript.corejs,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome51: true,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.species, Promise.prototype.then',
+ exec() {
+ /*
+ var promise = new Promise(function(resolve){ resolve(42); });
+ var FakePromise1 = promise.constructor = function(exec){ exec(function(){}, function(){}); };
+ var FakePromise2 = function(exec){ exec(function(){}, function(){}); };
+ Object.defineProperty(FakePromise1, Symbol.species, {value: FakePromise2});
+ return promise.then(function(){}) instanceof FakePromise2;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge13: false,
+ edge14: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: null,
+ ejs: null,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Symbol.replace',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/replace',
+ exec() {
+ /*
+ var O = {};
+ O[Symbol.replace] = function(){
+ return 42;
+ };
+ return ''.replace(O) === 42;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ chrome50: true,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.search',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/search',
+ exec() {
+ /*
+ var O = {};
+ O[Symbol.search] = function(){
+ return 42;
+ };
+ return ''.search(O) === 42;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ chrome50: true,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.split',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/split',
+ exec() {
+ /*
+ var O = {};
+ O[Symbol.split] = function(){
+ return 42;
+ };
+ return ''.split(O) === 42;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ chrome50: true,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.match',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match',
+ exec() {
+ /*
+ var O = {};
+ O[Symbol.match] = function(){
+ return 42;
+ };
+ return ''.match(O) === 42;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ chrome50: true,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.match, RegExp constructor',
+ exec() {
+ /*
+ var re = /./;
+ re[Symbol.match] = false;
+ var foo = {constructor: RegExp};
+ foo[Symbol.match] = true;
+ return RegExp(re) !== re && RegExp(foo) === foo;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ chrome50: true,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.match, String.prototype.startsWith',
+ exec() {
+ /*
+ var re = /./;
+ try {
+ '/./'.startsWith(re);
+ } catch(e){
+ re[Symbol.match] = false;
+ return '/./'.startsWith(re);
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ ie11: false,
+ edge14: edge.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Symbol.match, String.prototype.endsWith',
+ exec() {
+ /*
+ var re = /./;
+ try {
+ '/./'.endsWith(re);
+ } catch(e){
+ re[Symbol.match] = false;
+ return '/./'.endsWith(re);
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ ie11: false,
+ edge14: edge.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Symbol.match, String.prototype.includes',
+ exec() {
+ /*
+ var re = /./;
+ try {
+ '/./'.includes(re);
+ } catch(e){
+ re[Symbol.match] = false;
+ return '/./'.includes(re);
+ }
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ firefox2: false,
+ firefox40: true,
+ opera10_50: false,
+ ie11: false,
+ edge14: edge.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Symbol.toPrimitive',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive',
+ exec() {
+ /*
+ var a = {}, b = {}, c = {};
+ var passed = 0;
+ a[Symbol.toPrimitive] = function(hint) { passed += hint === "number"; return 0; };
+ b[Symbol.toPrimitive] = function(hint) { passed += hint === "string"; return 0; };
+ c[Symbol.toPrimitive] = function(hint) { passed += hint === "default"; return 0; };
+
+ a >= 0;
+ b in {};
+ c == 0; // eslint-disable-line eqeqeq
+ return passed === 3;
+ */
+ },
+ res: {
+ ejs: true,
+ typescript1corejs2: typescript.fallthrough,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox44: true,
+ opera10_50: false,
+ chrome47: true,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.toStringTag',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag',
+ exec() {
+ /*
+ var a = {};
+ a[Symbol.toStringTag] = "foo";
+ return (a + "") === "[object foo]";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome40: chrome.experimental,
+ chrome49: true,
+ node4: 'flagged',
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.toStringTag affects existing built-ins',
+ exec() {
+ /*
+ var s = Symbol.toStringTag;
+ var passed = true;
+ [
+ [Array.prototype, []],
+ [String.prototype, ''],
+ [arguments, arguments],
+ [Function.prototype, function(){}],
+ [Error.prototype, new Error()],
+ [Boolean.prototype, true],
+ [Number.prototype, 2],
+ [Date.prototype, new Date()],
+ [RegExp.prototype, /./]
+ ].forEach(function(pair){
+ pair[0][s] = "foo";
+ passed &= (Object.prototype.toString.call(pair[1]) === "[object foo]");
+ delete pair[0][s];
+ });
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome40: chrome.experimental,
+ chrome49: true,
+ chrome55: false,
+ chrome57: true,
+ node4: 'flagged',
+ node8: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ duktape2_5: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.toStringTag, new built-ins',
+ exec() {
+ /*
+ var passed = true;
+ var s = Symbol.toStringTag;
+ [
+ [String, "String Iterator"],
+ [Array, "Array Iterator"],
+ [Map, "Map Iterator"],
+ [Set, "Set Iterator"]
+ ].forEach(function(pair){
+ var iterProto = Object.getPrototypeOf(new pair[0]()[Symbol.iterator]());
+ passed = passed
+ && iterProto.hasOwnProperty(s)
+ && iterProto[s] === pair[1];
+ });
+ passed = passed
+ && Object.getPrototypeOf(function*(){})[s] === "GeneratorFunction"
+ && Object.getPrototypeOf(function*(){}())[s] === "Generator"
+ && Map.prototype[s] === "Map"
+ && Set.prototype[s] === "Set"
+ && ArrayBuffer.prototype[s] === "ArrayBuffer"
+ && DataView.prototype[s] === "DataView"
+ && Promise.prototype[s] === "Promise"
+ && Symbol.prototype[s] === "Symbol"
+ && typeof Object.getOwnPropertyDescriptor(
+ Object.getPrototypeOf(Int8Array).prototype, Symbol.toStringTag).get === "function";
+ return passed;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome49: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Symbol.toStringTag, misc. built-ins',
+ exec() {
+ /*
+ var s = Symbol.toStringTag;
+ return Math[s] === "Math"
+ && JSON[s] === "JSON";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox51: true,
+ opera10_50: false,
+ chrome40: chrome.experimental,
+ chrome49: true,
+ node4: 'flagged',
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Symbol.unscopables',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables',
+ exec() {
+ /*
+ var a = { foo: 1, bar: 2 };
+ a[Symbol.unscopables] = { bar: true };
+ with (a) {
+ return foo === 1 && typeof bar === "undefined";
+ }
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox48: true,
+ chrome38: true,
+ opera10_50: false,
+ safari9: true,
+ ejs: {
+ val: false,
+ note_id: 'ejs-no-with',
+ note_html: 'with
is not supported in ejs',
+ },
+ typescript1corejs2: typescript.fallthrough,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'RegExp.prototype properties',
+ category: 'built-in extensions',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/prototype',
+ subtests: [
+ {
+ name: 'RegExp.prototype.flags',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/flags',
+ exec() {
+ /*
+ return /./igm.flags === "gim" && /./.flags === "";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ safari9: true,
+ xs6: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ ie11: false,
+ edge14: edge.experimental,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'RegExp.prototype[Symbol.match]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@match',
+ exec() {
+ /*
+ return typeof RegExp.prototype[Symbol.match] === 'function';
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ chrome50: true,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'RegExp.prototype[Symbol.replace]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@replace',
+ exec() {
+ /*
+ return typeof RegExp.prototype[Symbol.replace] === 'function';
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ chrome50: true,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype[Symbol.split]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@split',
+ exec() {
+ /*
+ return typeof RegExp.prototype[Symbol.split] === 'function';
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ chrome50: true,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype[Symbol.search]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@search',
+ exec() {
+ /*
+ return typeof RegExp.prototype[Symbol.search] === 'function';
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ chrome50: true,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'RegExp[Symbol.species]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/@@species',
+ exec() {
+ /*
+ var prop = Object.getOwnPropertyDescriptor(RegExp, Symbol.species);
+ return 'get' in prop && RegExp[Symbol.species] === RegExp;
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox49: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ // As this one is Annex B, it is separate from the above.
+ {
+ name: 'RegExp.prototype.compile',
+ category: 'annex b',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-regexp.prototype.compile',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/compile',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ if (typeof RegExp.prototype.compile !== 'function')
+ return false
+ var rx = /a/;
+ rx.compile('b');
+ return rx.test('b');
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ {
+ name: 'returns this',
+ exec() {
+ /*
+ var rx = /a/;
+ return rx.compile('b') === rx;
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: true,
+ opera10_50: false,
+ chrome5: false,
+ chrome57: true,
+ safari5_1: false,
+ safari10: true,
+ konq4_14: null,
+ rhino1_7_13: true,
+ node0_12: false,
+ node8: true,
+ android4_0: false,
+ xs6: null,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'RegExp syntax extensions',
+ category: 'annex b',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-regular-expressions-patterns',
+ subtests: [
+ {
+ name: 'hyphens in character sets',
+ exec() {
+ /*
+ return /[\w-_]/.exec("-")[0] === "-";
+ */
+ },
+ res: {
+ ejs: true,
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'invalid character escapes',
+ exec() {
+ /*
+ return /\z/.exec("\\z")[0] === "z"
+ && /[\z]/.exec("[\\z]")[0] === "z";
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'invalid control-character escapes',
+ exec() {
+ /*
+ return /\c2/.exec("\\c2")[0] === "\\c2";
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari4: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ {
+ name: 'invalid Unicode escapes',
+ exec() {
+ /*
+ return /\u1/.exec("u1")[0] === "u1"
+ && /[\u1]/.exec("u")[0] === "u";
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ opera10_50: false,
+ chrome5: true,
+ safari3_1: true,
+ konq4_14: true,
+ rhino1_7_13: false,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'invalid hexadecimal escapes',
+ exec() {
+ /*
+ return /\x1/.exec("x1")[0] === "x1"
+ && /[\x1]/.exec("x")[0] === "x";
+ */
+ },
+ res: {
+ ie10: true,
+ firefox2: false,
+ firefox4: true,
+ opera10_50: false,
+ chrome5: true,
+ safari3_1: true,
+ konq4_14: true,
+ rhino1_7_13: false,
+ node0_12: true,
+ android4_0: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'incomplete patterns and quantifiers',
+ exec() {
+ /*
+ return /x{1/.exec("x{1")[0] === "x{1"
+ && /x]1/.exec("x]1")[0] === "x]1";
+ */
+ },
+ res: {
+ ejs: true,
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'octal escape sequences',
+ exec() {
+ /*
+ return /\041/.exec("!")[0] === "!"
+ && /[\041]/.exec("!")[0] === "!";
+ */
+ },
+ res: {
+ ejs: true,
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'invalid backreferences become octal escapes',
+ exec() {
+ /*
+ return /\41/.exec("!")[0] === "!"
+ && /[\41]/.exec("!")[0] === "!";
+ */
+ },
+ res: {
+ ejs: true,
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Array static methods',
+ category: 'built-in extensions',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-array-constructor',
+ subtests: [
+ {
+ name: 'Array.from, array-like objects',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/from#Array_from_an_Array-like_object_(arguments)',
+ exec() {
+ /*
+ return Array.from({ 0: "foo", 1: "bar", length: 2 }) + '' === "foo,bar";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ es6shim: true,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.from, generator instances',
+ exec() {
+ /*
+ var iterable = (function*(){ yield 1; yield 2; yield 3; }());
+ return Array.from(iterable) + '' === "1,2,3";
+ */
+ },
+ res: {
+ tr: true,
+ ejs: true,
+ babel6corejs2: true,
+ typescript1corejs2: typescript.fallthrough,
+ closure: true,
+ es6shim: true,
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ chrome45: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ node4: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.from, generic iterables',
+ exec() {
+ /*
+ var iterable = global.__createIterableObject([1, 2, 3]);
+ return Array.from(iterable) + '' === "1,2,3";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Array.from, instances of generic iterables',
+ exec() {
+ /*
+ var iterable = global.__createIterableObject([1, 2, 3]);
+ return Array.from(Object.create(iterable)) + '' === "1,2,3";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ tr: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Array.from map function, array-like objects',
+ exec() {
+ /*
+ return Array.from({ 0: "foo", 1: "bar", length: 2 }, function(e, i) {
+ return e + this.baz + i;
+ }, { baz: "d" }) + '' === "food0,bard1";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure20180610: true,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.from map function, generator instances',
+ exec() {
+ /*
+ var iterable = (function*(){ yield "foo"; yield "bar"; yield "bal"; }());
+ return Array.from(iterable, function(e, i) {
+ return e + this.baz + i;
+ }, { baz: "d" }) + '' === "food0,bard1,bald2";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: true,
+ closure20180610: true,
+ typescript1corejs2: typescript.fallthrough,
+ es6shim: true,
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ chrome45: true,
+ ie11: false,
+ edge12: edge.experimental,
+ node4: true,
+ edge13: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.from map function, generic iterables',
+ exec() {
+ /*
+ var iterable = global.__createIterableObject(["foo", "bar", "bal"]);
+ return Array.from(iterable, function(e, i) {
+ return e + this.baz + i;
+ }, { baz: "d" }) + '' === "food0,bard1,bald2";
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure20180610: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Array.from map function, instances of iterables',
+ exec() {
+ /*
+ var iterable = global.__createIterableObject(["foo", "bar", "bal"]);
+ return Array.from(Object.create(iterable), function(e, i) {
+ return e + this.baz + i;
+ }, { baz: "d" }) + '' === "food0,bard1,bald2";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure20180610: true,
+ typescript1corejs2: typescript.corejs,
+ tr: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Array.from, iterator closing',
+ exec() {
+ /*
+ var closed = false;
+ var iter = global.__createIterableObject([1, 2, 3], {
+ 'return': function(){ closed = true; return {}; }
+ });
+ try {
+ Array.from(iter, function() { throw 42 });
+ } catch(e){}
+ return closed;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox36: true,
+ opera10_50: false,
+ chrome51: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Array.of',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/of',
+ exec() {
+ /*
+ return typeof Array.of === 'function' &&
+ Array.of(2)[0] === 2;
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome39: chrome.experimental,
+ chrome40: false,
+ chrome45: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array[Symbol.species]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@species',
+ exec() {
+ /*
+ var prop = Object.getOwnPropertyDescriptor(Array, Symbol.species);
+ return 'get' in prop && Array[Symbol.species] === Array;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Array.prototype methods',
+ category: 'built-in extensions',
+ significance: 'medium',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-the-array-prototype-object',
+ subtests: [
+ {
+ name: 'Array.prototype.copyWithin',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/copyWithin',
+ exec() {
+ /*
+ return typeof Array.prototype.copyWithin === 'function';
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ safari9: true,
+ chrome45: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.prototype.find',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/find',
+ exec() {
+ /*
+ return typeof Array.prototype.find === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome45: true,
+ safari7_1: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.prototype.findIndex',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/findIndex',
+ exec() {
+ /*
+ return typeof Array.prototype.findIndex === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome45: true,
+ safari7_1: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.prototype.fill',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/fill',
+ exec() {
+ /*
+ return typeof Array.prototype.fill === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox31: true,
+ opera10_50: false,
+ chrome36: chrome.experimental,
+ chrome45: true,
+ safari7_1: true,
+ node0_12: 'flagged',
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.prototype.keys',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/keys',
+ exec() {
+ /*
+ return typeof Array.prototype.keys === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox28: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.prototype.values',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values',
+ exec() {
+ /*
+ return typeof Array.prototype.values === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ chrome51: true,
+ chrome52: {
+ val: false,
+ note_id: 'cr-array-prototype-values',
+ note_html:
+ 'The feature was disabled due to a compatibility issue.',
+ },
+ chrome66: true,
+ safari9: true,
+ firefox2: false,
+ firefox17: {
+ val: false,
+ note_id: 'fx-array-prototype-iterator',
+ note_html: 'Available from Firefox 17 up to 27 as the non-standard Array.prototype.iterator
',
+ },
+ firefox27: {
+ val: false,
+ note_id: 'fx-array-prototype-iterator-2',
+ note_html:
+ 'Available from Firefox 27 up to 35 as the non-standard Array.prototype["@@iterator"]
',
+ },
+ firefox36: {
+ val: false,
+ note_id: 'fx-array-prototype-iterator-3',
+ note_html: 'Available from Firefox 36 up to 47 as Array.prototype[Symbol.iterator]
',
+ },
+ firefox48: true,
+ firefox49: {
+ val: false,
+ note_id: 'fx-array-prototype-values',
+ note_html:
+ 'The feature is enabled only in Firefox Nightly due to a compatibility issue.',
+ },
+ firefox60: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome38: { val: false, note_id: 'fx-array-prototype-iterator-3' },
+ node0_12: true,
+ node4: false,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.prototype.entries',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries',
+ exec() {
+ /*
+ return typeof Array.prototype.entries === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox28: true,
+ opera10_50: false,
+ chrome30: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array.prototype.splice',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/splice',
+ exec() {
+ /*
+ if ([0, 1, 2].splice(0).length !== 3) {
+ // IE <= 8 and other pre-ES6 engines fail this check
+ return false;
+ }
+
+ var a = [1, 2];
+ var result = a.splice();
+ if (a.length !== 2 || result.length !== 0) {
+ // Safari 5.0 has this bug
+ return false;
+ }
+
+ var obj = {};
+ Array.prototype.splice.call(obj, 0, 0, 1);
+ if (obj.length !== 1) {
+ return false;
+ }
+
+ var spliceWorksWithLargeSparseArrays = (function () {
+ // Per https://github.com/es-shims/es5-shim/issues/295
+ // Safari 7/8 breaks with sparse arrays of size 1e5 or greater
+ var arr = new Array(1e5);
+ // note: the index MUST be 8 or larger or the test will false pass
+ arr[8] = 'x';
+ arr.splice(1, 1);
+ for (var i = 0; i < arr.length; i += 1) {
+ if (arr[i] === 'x') {
+ return i === 7;
+ }
+ }
+ return false;
+ }());
+ var spliceWorksWithSmallSparseArrays = (function () {
+ // Per https://github.com/es-shims/es5-shim/issues/295
+ // Opera 12.15 breaks on this, no idea why.
+ var n = 256;
+ var arr = [];
+ arr[n] = 'a';
+ arr.splice(n + 1, 0, 'b');
+ return arr[n] === 'a';
+ }());
+
+ return spliceWorksWithLargeSparseArrays && spliceWorksWithSmallSparseArrays;
+ */
+ },
+ res: {
+ ie8: false,
+ ie9: true,
+ ie11: true,
+ chrome15: false,
+ chrome16: true,
+ chrome18: true,
+ chrome20: true,
+ chrome40: true,
+ chrome50: true,
+ chrome101: true,
+ firefox3: null,
+ firefox13: true,
+ firefox15: true,
+ firefox20: true,
+ opera10_50: null,
+ opera12: false,
+ opera12_10: false,
+ safari4: false,
+ safari5: false,
+ safari5_1: true,
+ safari15: true,
+ graalvm21_3_3: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Array.prototype[Symbol.iterator]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@iterator',
+ exec() {
+ /*
+ return typeof Array.prototype[Symbol.iterator] === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ safari9: true,
+ firefox2: false,
+ firefox17: {
+ val: false,
+ note_id: 'fx-array-prototype-iterator',
+ },
+ firefox27: {
+ val: false,
+ note_id: 'fx-array-prototype-iterator-2',
+ },
+ firefox36: true,
+ opera10_50: false,
+ chrome37: chrome.experimental,
+ chrome38: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Array iterator prototype chain',
+ exec() {
+ /*
+ // Iterator instance
+ var iterator = [][Symbol.iterator]();
+ // %ArrayIteratorPrototype%
+ var proto1 = Object.getPrototypeOf(iterator);
+ // %IteratorPrototype%
+ var proto2 = Object.getPrototypeOf(proto1);
+
+ return proto2.hasOwnProperty(Symbol.iterator) &&
+ !proto1 .hasOwnProperty(Symbol.iterator) &&
+ !iterator .hasOwnProperty(Symbol.iterator) &&
+ iterator[Symbol.iterator]() === iterator;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ ejs: true,
+ typescript1corejs2: typescript.corejs,
+ safari9: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ chrome51: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype[Symbol.unscopables]',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/@@unscopables',
+ exec() {
+ /*
+ var unscopables = Array.prototype[Symbol.unscopables];
+ if (!unscopables) {
+ return false;
+ }
+ var ns = "find,findIndex,fill,copyWithin,entries,keys,values".split(",");
+ for (var i = 0; i < ns.length; i++) {
+ if (Array.prototype[ns[i]] && !unscopables[ns[i]]) return false;
+ }
+ return true;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Number properties',
+ category: 'built-in extensions',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-isfinite-number',
+ subtests: [
+ {
+ name: 'Number.isFinite',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isFinite',
+ exec() {
+ /*
+ return typeof Number.isFinite === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox16: true,
+ opera10_50: false,
+ chrome19: true,
+ safari9: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_1: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Number.isInteger',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isInteger',
+ exec() {
+ /*
+ return typeof Number.isInteger === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox16: true,
+ opera10_50: false,
+ chrome34: true,
+ safari9: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Number.isSafeInteger',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isSafeInteger',
+ exec() {
+ /*
+ return typeof Number.isSafeInteger === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox32: true,
+ opera10_50: false,
+ chrome34: true,
+ safari9: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Number.isNaN',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/isNaN',
+ exec() {
+ /*
+ return typeof Number.isNaN === 'function';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox15: true,
+ opera10_50: false,
+ chrome19: true,
+ safari9: true,
+ konq4_14: true,
+ node0_12: true,
+ android4_1: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Number.parseFloat',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseFloat',
+ exec() {
+ /*
+ var actualGlobal = Function('return this')();
+ return typeof Number.parseFloat === 'function'
+ && Number.parseFloat === actualGlobal.parseFloat;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ chrome34: true,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox25: true,
+ opera10_50: false,
+ node0_12: true,
+ safari9: true,
+ typescript1corejs2: typescript.corejs,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Number.parseInt',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/parseInt',
+ exec() {
+ /*
+ var actualGlobal = Function('return this')();
+ return typeof Number.parseInt === 'function'
+ && Number.parseInt === actualGlobal.parseInt;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ chrome34: true,
+ ie11: false,
+ edge12: true,
+ es6shim: true,
+ firefox25: true,
+ opera10_50: false,
+ node0_12: true,
+ safari9: true,
+ typescript1corejs2: typescript.corejs,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Number.EPSILON',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/EPSILON',
+ exec() {
+ /*
+ return typeof Number.EPSILON === 'number';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_14: true,
+ },
+ },
+ {
+ name: 'Number.MIN_SAFE_INTEGER',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MIN_SAFE_INTEGER',
+ exec() {
+ /*
+ return typeof Number.MIN_SAFE_INTEGER === 'number';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox31: true,
+ opera10_50: false,
+ chrome34: true,
+ safari9: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ {
+ name: 'Number.MAX_SAFE_INTEGER',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER',
+ exec() {
+ /*
+ return typeof Number.MAX_SAFE_INTEGER === 'number';
+ */
+ },
+ res: {
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox31: true,
+ opera10_50: false,
+ chrome34: true,
+ safari9: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Math methods',
+ category: 'built-in extensions',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-math',
+ subtests: (function () {
+ const methods = {
+ clz32: {
+ ejs: true,
+ tr: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox31: true,
+ opera10_50: false,
+ chrome35: chrome.experimental,
+ chrome38: true,
+ safari9: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ imul: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox23: true,
+ opera10_50: false,
+ chrome21: {
+ val: true,
+ note_id: 'chromu-imul',
+ note_html: 'Available since Chrome 28',
+ },
+ chrome30: true,
+ safari7: true,
+ safari10: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ sign: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome33: chrome.experimental,
+ chrome38: true,
+ safari9: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ log10: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ log2: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ log1p: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome35: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ expm1: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome35: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ cosh: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ sinh: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ tanh: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ acosh: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ asinh: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ atanh: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ trunc: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure: true,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome33: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ fround: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ closure20181125: {
+ val: false,
+ note_id: 'closure-mathfround',
+ note_html: 'Requires native support for Float32Array
',
+ },
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox26: true,
+ opera10_50: false,
+ chrome35: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ cbrt: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ closure: true,
+ typescript1corejs2: typescript.corejs,
+ tr: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox25: true,
+ opera10_50: false,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ }
+ const eqFn = ' === "function"'
+ return Object.keys(methods)
+ .map(function (m) {
+ return {
+ name: `Math.${m}`,
+ mdn: `https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/${m}`,
+ // TODO: fix this eval
+ // exec: eval(`0,function(){/*\n return typeof Math.${m}${eqFn};\n*/}`),
+ exec() {
+ return false
+ },
+ res: methods[m],
+ }
+ })
+ .concat({
+ name: 'Math.hypot',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/hypot',
+ exec() {
+ /*
+ return Math.hypot() === 0 &&
+ Math.hypot(1) === 1 &&
+ Math.hypot(9, 12, 20) === 25 &&
+ Math.hypot(27, 36, 60, 100) === 125;
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ closure20190215: true,
+ typescript1corejs2: typescript.corejs,
+ tr: true,
+ es6shim: true,
+ firefox2: false,
+ firefox27: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ chrome34: chrome.experimental,
+ chrome38: true,
+ safari7_1: true,
+ konq4_14: true,
+ node0_12: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: true,
+ },
+ })
+ })(),
+ },
+ {
+ name: 'Date.prototype[Symbol.toPrimitive]',
+ category: 'built-in extensions',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-date.prototype-@@toprimitive',
+ mdn: 'https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/@@toPrimitive',
+ exec() {
+ /*
+ var tp = Date.prototype[Symbol.toPrimitive];
+ return tp.call(Object(2), "number") === 2
+ && tp.call(Object(2), "string") === "2"
+ && tp.call(Object(2), "default") === "2";
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox44: true,
+ opera10_50: false,
+ chrome47: true,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ duktape2_3: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array is subclassable',
+ category: 'subclassing',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-array-constructor',
+ subtests: [
+ {
+ name: 'length property (accessing)',
+ exec() {
+ /*
+ class C extends Array {}
+ var c = new C();
+ var len1 = c.length;
+ c[2] = 'foo';
+ var len2 = c.length;
+ return len1 === 0 && len2 === 3;
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ node4: 'strict',
+ chrome43: 'strict',
+ chrome49: true,
+ safari9: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'length property (setting)',
+ exec() {
+ /*
+ class C extends Array {}
+ var c = new C();
+ c[2] = 'foo';
+ c.length = 1;
+ return c.length === 1 && !(2 in c);
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ node4: 'strict',
+ chrome43: 'strict',
+ chrome49: true,
+ safari9: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'correct prototype chain',
+ exec() {
+ /*
+ class C extends Array {}
+ var c = new C();
+ return c instanceof C && c instanceof Array && Object.getPrototypeOf(C) === Array;
+ */
+ },
+ res: {
+ babel6corejs2: { val: false, note_id: 'compiler-proto' },
+ closure: false,
+ node4: 'strict',
+ chrome43: 'strict',
+ chrome49: true,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.isArray support',
+ exec() {
+ /*
+ class C extends Array {}
+ return Array.isArray(new C());
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ safari9: true,
+ chrome43: 'strict',
+ chrome49: true,
+ opera10_50: false,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.concat',
+ exec() {
+ /*
+ class C extends Array {}
+ var c = new C();
+ return c.concat(1) instanceof C;
+ */
+ },
+ res: {
+ closure: false,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.filter',
+ exec() {
+ /*
+ class C extends Array {}
+ var c = new C();
+ return c.filter(Boolean) instanceof C;
+ */
+ },
+ res: {
+ closure: false,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.map',
+ exec() {
+ /*
+ class C extends Array {}
+ var c = new C();
+ return c.map(Boolean) instanceof C;
+ */
+ },
+ res: {
+ closure: false,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.slice',
+ exec() {
+ /*
+ class C extends Array {}
+ var c = new C();
+ c.push(2,4,6);
+ return c.slice(1,2) instanceof C;
+ */
+ },
+ res: {
+ closure: false,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.prototype.splice',
+ exec() {
+ /*
+ class C extends Array {}
+ var c = new C();
+ c.push(2,4,6);
+ return c.splice(1,2) instanceof C;
+ */
+ },
+ res: {
+ closure: false,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox48: true,
+ opera10_50: false,
+ chrome50: chrome.experimental,
+ chrome51: true,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.from',
+ exec() {
+ /*
+ class C extends Array {}
+ return C.from({ length: 0 }) instanceof C;
+ */
+ },
+ res: {
+ tr: { val: false, note_id: 'compiler-proto' },
+ babel6corejs2: { val: false, note_id: 'compiler-proto' },
+ closure: false,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ ejs: true,
+ chrome45: 'strict',
+ chrome49: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Array.of',
+ exec() {
+ /*
+ class C extends Array {}
+ return C.of(0) instanceof C;
+ */
+ },
+ res: {
+ tr: { val: false, note_id: 'compiler-proto' },
+ babel6corejs2: { val: false, note_id: 'compiler-proto' },
+ closure: false,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ chrome45: 'strict',
+ chrome49: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'RegExp is subclassable',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-regexp-constructor',
+ category: 'subclassing',
+ significance: 'tiny',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ class R extends RegExp {}
+ var r = new R("baz","g");
+ return r.global && r.source === "baz";
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ safari9: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'correct prototype chain',
+ exec() {
+ /*
+ class R extends RegExp {}
+ var r = new R("baz","g");
+ return r instanceof R && r instanceof RegExp && Object.getPrototypeOf(R) === RegExp;
+ */
+ },
+ res: {
+ babel6corejs2: { val: false, note_id: 'compiler-proto' },
+ closure: false,
+ node4: 'strict',
+ chrome43: 'strict',
+ chrome49: true,
+ typescript1corejs2: false,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype.exec',
+ exec() {
+ /*
+ class R extends RegExp {}
+ var r = new R("baz","g");
+ return r.exec("foobarbaz")[0] === "baz" && r.lastIndex === 9;
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ safari9: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node5: 'strict',
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype.test',
+ exec() {
+ /*
+ class R extends RegExp {}
+ var r = new R("baz");
+ return r.test("foobarbaz");
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ safari9: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ node5: 'strict',
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Function is subclassable',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-function-constructor',
+ category: 'subclassing',
+ significance: 'tiny',
+ subtests: [
+ {
+ name: 'can be called',
+ exec() {
+ /*
+ class C extends Function {}
+ var c = new C("return 'foo';");
+ return c() === 'foo';
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'correct prototype chain',
+ exec() {
+ /*
+ class C extends Function {}
+ var c = new C("return 'foo';");
+ return c instanceof C && c instanceof Function && Object.getPrototypeOf(C) === Function;
+ */
+ },
+ res: {
+ babel6corejs2: { val: false, note_id: 'compiler-proto' },
+ closure: false,
+ typescript1corejs2: false,
+ ie11: false,
+ edge12: edge.experimental,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'can be used with "new"',
+ exec() {
+ /*
+ class C extends Function {}
+ var c = new C("this.bar = 2;");
+ c.prototype.baz = 3;
+ return new c().bar === 2 && new c().baz === 3;
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome48: false,
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Function.prototype.call',
+ exec() {
+ /*
+ class C extends Function {}
+ var c = new C("x", "return this.bar + x;");
+ return c.call({bar:1}, 2) === 3;
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Function.prototype.apply',
+ exec() {
+ /*
+ class C extends Function {}
+ var c = new C("x", "return this.bar + x;");
+ return c.apply({bar:1}, [2]) === 3;
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Function.prototype.bind',
+ exec() {
+ /*
+ class C extends Function {}
+ var c = new C("x", "y", "return this.bar + x + y;").bind({bar:1}, 2);
+ return c(6) === 9 && c instanceof C;
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: false,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ chrome48: chrome.experimental,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Promise is subclassable',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-function-constructor',
+ category: 'subclassing',
+ significance: 'small',
+ subtests: [
+ {
+ name: 'basic functionality',
+ exec() {
+ /*
+ class P extends Promise {}
+ var p1 = new P(function(resolve, reject) { resolve("foo"); });
+ var p2 = new P(function(resolve, reject) { reject("quux"); });
+ var score = +(p1 instanceof P);
+
+ function thenFn(result) { score += (result === "foo"); check(); }
+ function catchFn(result) { score += (result === "quux"); check(); }
+ function shouldNotRun(result) { score = -Infinity; }
+
+ p1.then(thenFn, shouldNotRun);
+ p2.then(shouldNotRun, catchFn);
+ p1.catch(shouldNotRun);
+ p2.catch(catchFn);
+
+ p1.then(function() {
+ // P.prototype.then() should return a new P
+ score += p1.then() instanceof P && p1.then() !== p1;
+ check();
+ });
+
+ function check() {
+ if (score === 5) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ closure: false,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari10: true,
+ node5: 'strict',
+ xs6: true,
+ ejs: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'correct prototype chain',
+ exec() {
+ /*
+ class C extends Promise {}
+ var c = new C(function(resolve, reject) { resolve("foo"); });
+ return c instanceof C && c instanceof Promise && Object.getPrototypeOf(C) === Promise;
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari10: true,
+ node5: 'strict',
+ xs6: true,
+ ejs: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Promise.all',
+ exec() {
+ /*
+ class P extends Promise {}
+ var fulfills = P.all([
+ new Promise(function(resolve) { setTimeout(resolve,2000,"foo"); }),
+ new Promise(function(resolve) { setTimeout(resolve,1000,"bar"); })
+ ]);
+ var rejects = P.all([
+ new Promise(function(_, reject) { setTimeout(reject, 2000,"baz"); }),
+ new Promise(function(_, reject) { setTimeout(reject, 1000,"qux"); })
+ ]);
+ var score = +(fulfills instanceof P);
+ fulfills.then(function(result) { score += (result + "" === "foo,bar"); check(); });
+ rejects.catch(function(result) { score += (result === "qux"); check(); });
+
+ function check() {
+ if (score === 3) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ closure: false,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari10: true,
+ node5: 'strict',
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Promise.race',
+ exec() {
+ /*
+ class P extends Promise {}
+ var fulfills = P.race([
+ new Promise(function(resolve) { setTimeout(resolve,1000,"foo"); }),
+ new Promise(function(_, reject) { setTimeout(reject, 2000,"bar"); })
+ ]);
+ var rejects = P.race([
+ new Promise(function(_, reject) { setTimeout(reject, 1000,"baz"); }),
+ new Promise(function(resolve) { setTimeout(resolve,2000,"qux"); })
+ ]);
+ var score = +(fulfills instanceof P);
+ fulfills.then(function(result) { score += (result === "foo"); check(); });
+ rejects.catch(function(result) { score += (result === "baz"); check(); });
+
+ function check() {
+ if (score === 3) asyncTestPassed();
+ }
+ */
+ },
+ res: {
+ closure: false,
+ typescript1corejs2: false,
+ chrome43: 'strict',
+ chrome49: true,
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ safari10: true,
+ node5: 'strict',
+ xs6: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'miscellaneous subclassables',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-boolean-constructor',
+ category: 'subclassing',
+ significance: 'tiny',
+ subtests: [
+ {
+ name: 'Boolean is subclassable',
+ exec() {
+ /*
+ class C extends Boolean {}
+ var c = new C(true);
+ return c instanceof Boolean
+ && c instanceof C
+ && c == true; // eslint-disable-line eqeqeq
+ */
+ },
+ res: {
+ closure: false,
+ safari10: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Number is subclassable',
+ exec() {
+ /*
+ class C extends Number {}
+ var c = new C(6);
+ return c instanceof Number
+ && c instanceof C
+ && +c === 6;
+ */
+ },
+ res: {
+ closure: false,
+ safari10: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'String is subclassable',
+ exec() {
+ /*
+ class C extends String {}
+ var c = new C("golly");
+ return c instanceof String
+ && c instanceof C
+ && c + '' === "golly"
+ && c[0] === "g"
+ && c.length === 5;
+ */
+ },
+ res: {
+ closure: false,
+ safari10: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Error is subclassable',
+ exec() {
+ /*
+ class C extends Error {}
+ var c = new C();
+ return c instanceof Error
+ && c instanceof C
+ && Object.prototype.toString.call(c) === "[object Error]";
+ */
+ },
+ res: {
+ closure: false,
+ safari10: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Map is subclassable',
+ exec() {
+ /*
+ var key = {};
+ class M extends Map {}
+ var map = new M();
+
+ map.set(key, 123);
+
+ return map instanceof M && map.has(key) && map.get(key) === 123;
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ safari10: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Set is subclassable',
+ exec() {
+ /*
+ var obj = {};
+ class S extends Set {}
+ var set = new S();
+
+ set.add(123);
+ set.add(123);
+
+ return set instanceof S && set.has(123);
+ */
+ },
+ res: {
+ closure: false,
+ closure20200614: true,
+ safari10: true,
+ chrome43: 'strict',
+ chrome49: true,
+ node4: 'strict',
+ ie11: false,
+ edge13: true,
+ firefox2: false,
+ firefox45: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ jxa: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: hermes.class,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'own property order',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-ordinary-object-internal-methods-and-internal-slots-ownpropertykeys',
+ category: 'misc',
+ significance: 'tiny',
+ subtests: [
+ {
+ name: 'Object.keys',
+ exec() {
+ /*
+ var obj = {
+ // Non-negative integer names appear first in value order
+ 2: true,
+ 0: true,
+ 1: true,
+ // Other string names appear in source order
+ ' ': true,
+ // Non-negative integers are sorted above other names
+ 9: true,
+ D: true,
+ B: true,
+ // Negative integers are treated as other names
+ '-1': true
+ };
+ // Other string names are added in order of creation
+ obj.A = true;
+ // Non-negative integer names, conversely, ignore order of creation
+ obj[3] = true;
+ // Having a total of 20+ properties doesn't affect property order
+ "EFGHIJKLMNOPQRSTUVWXYZ".split('').forEach(function(key){
+ obj[key] = true;
+ });
+ // Object.defineProperty doesn't affect the above rules
+ Object.defineProperty(obj, 'C', { value: true, enumerable: true });
+ Object.defineProperty(obj, '4', { value: true, enumerable: true });
+ // Deleting and reinserting a property doesn't preserve its position
+ delete obj[2];
+ obj[2] = true;
+
+ var forInOrder = '';
+ for(var key in obj)forInOrder += key;
+
+ return Object.keys(obj).join('') === forInOrder;
+ */
+ },
+ res: {
+ ie10: true,
+ chrome5: true,
+ firefox2: false,
+ firefox4: true,
+ node0_12: true,
+ opera10_50: false,
+ opera12: true,
+ safari4: true,
+ android4_0: true,
+ xs6: true,
+ phantom1_9: true,
+ ejs: false,
+ konq4_14: null,
+ rhino1_7_13: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'Object.getOwnPropertyNames',
+ exec() {
+ /*
+ var obj = {
+ 2: true,
+ 0: true,
+ 1: true,
+ ' ': true,
+ 9: true,
+ D: true,
+ B: true,
+ '-1': true
+ };
+ obj.A = true;
+ obj[3] = true;
+ "EFGHIJKLMNOPQRSTUVWXYZ".split('').forEach(function(key){
+ obj[key] = true;
+ });
+ Object.defineProperty(obj, 'C', { value: true, enumerable: true });
+ Object.defineProperty(obj, '4', { value: true, enumerable: true });
+ delete obj[2];
+ obj[2] = true;
+
+ return Object.getOwnPropertyNames(obj).join('') === "012349 DB-1AEFGHIJKLMNOPQRSTUVWXYZC";
+ */
+ },
+ res: {
+ ie10: { val: true, note_id: 'ie_property_order' },
+ firefox2: false,
+ firefox44: true,
+ opera10_50: false,
+ opera12: true,
+ safari7_1: true,
+ xs6: true,
+ chrome49: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Object.assign',
+ exec() {
+ /*
+ var result = '';
+ var target = {};
+
+ "012349 DBACEFGHIJKLMNOPQRST".split('').concat(-1).forEach(function(key){
+ Object.defineProperty(target, key, {
+ set: function(){
+ result += key;
+ }
+ })
+ });
+
+ var obj = {2: 2, 0: 0, 1: 1, ' ': ' ', 9: 9, D: 'D', B: 'B', '-1': '-1'};
+ Object.defineProperty(obj, 'A', {value: 'A', enumerable: true});
+ Object.defineProperty(obj, '3', {value: '3', enumerable: true});
+ Object.defineProperty(obj, 'C', {value: 'C', enumerable: true});
+ Object.defineProperty(obj, '4', {value: '4', enumerable: true});
+ delete obj[2];
+ obj[2] = true;
+
+ "EFGHIJKLMNOPQRST".split('').forEach(function(key){
+ obj[key] = key;
+ });
+
+ Object.assign(target, obj);
+
+ return result === "012349 DB-1ACEFGHIJKLMNOPQRST";
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: { val: true, note_id: 'ie_property_order' },
+ firefox2: false,
+ firefox44: true,
+ opera10_50: false,
+ safari9: true,
+ xs6: true,
+ chrome49: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'JSON.stringify',
+ exec() {
+ /*
+ var obj = {
+ 2: true,
+ 0: true,
+ 1: true,
+ ' ': true,
+ 9: true,
+ D: true,
+ B: true,
+ '-1': true
+ };
+ obj.A = true;
+ obj[3] = true;
+ "EFGHIJKLMNOPQRSTUVWXYZ".split('').forEach(function(key){
+ obj[key] = true;
+ });
+ Object.defineProperty(obj, 'C', { value: true, enumerable: true });
+ Object.defineProperty(obj, '4', { value: true, enumerable: true });
+ delete obj[2];
+ obj[2] = true;
+
+ return JSON.stringify(obj) ===
+ '{"0":true,"1":true,"2":true,"3":true,"4":true,"9":true," ":true,"D":true,"B":true,"-1":true,"A":true,"E":true,"F":true,"G":true,"H":true,"I":true,"J":true,"K":true,"L":true,"M":true,"N":true,"O":true,"P":true,"Q":true,"R":true,"S":true,"T":true,"U":true,"V":true,"W":true,"X":true,"Y":true,"Z":true,"C":true}';
+ */
+ },
+ res: {
+ ie10: { val: true, note_id: 'ie_property_order' },
+ firefox2: false,
+ firefox44: true,
+ ejs: true,
+ chrome5: true,
+ node0_12: true,
+ opera10_50: false,
+ opera12: true,
+ safari7: true,
+ safari10: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'JSON.parse',
+ exec() {
+ /*
+ var result = '';
+ JSON.parse(
+ '{"0":true,"1":true,"2":true,"3":true,"4":true,"9":true," ":true,"D":true,"B":true,"-1":true,"E":true,"F":true,"G":true,"H":true,"I":true,"J":true,"K":true,"L":true,"A":true,"C":true}',
+ function reviver(k,v) {
+ result += k;
+ return v;
+ }
+ );
+ return result === "012349 DB-1EFGHIJKLAC";
+ */
+ },
+ res: {
+ ie10: {
+ val: true,
+ note_id: 'ie_property_order',
+ note_html:
+ 'Unlike other engines, Chakra sorts properties removed by delete
, then recreated by assignment, to their original creation positions, not their latest positions.',
+ },
+ firefox2: false,
+ firefox3_5: true,
+ firefox4: true,
+ chrome5: true,
+ node0_12: true,
+ opera10_50: true,
+ opera12: true,
+ safari4: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'Reflect.ownKeys, string key order',
+ exec() {
+ /*
+ var obj = {
+ 2: true,
+ 0: true,
+ 1: true,
+ ' ': true,
+ 9: true,
+ D: true,
+ B: true,
+ '-1': true
+ };
+ obj.A = true;
+ obj[3] = true;
+ "EFGHIJKLMNOPQRSTUVWXYZ".split('').forEach(function(key){
+ obj[key] = true;
+ });
+ Object.defineProperty(obj, 'C', { value: true, enumerable: true });
+ Object.defineProperty(obj, '4', { value: true, enumerable: true });
+ delete obj[2];
+ obj[2] = true;
+
+ return Reflect.ownKeys(obj).join('') === "012349 DB-1AEFGHIJKLMNOPQRSTUVWXYZC";
+ */
+ },
+ res: {
+ babel6corejs2: {
+ val: false,
+ note_id: 'forin-order',
+ note_html: 'This uses native for-in enumeration order, rather than the correct order.',
+ },
+ closure: { val: false, note_id: 'forin-order' },
+ typescript1corejs2: { val: false, note_id: 'forin-order' },
+ es6shim: { val: false, note_id: 'forin-order' },
+ firefox2: false,
+ firefox44: true,
+ opera10_50: false,
+ ie11: false,
+ edge12: true,
+ safari10: true,
+ xs6: true,
+ ejs: true,
+ chrome49: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Reflect.ownKeys, symbol key order',
+ exec() {
+ /*
+ var sym1 = Symbol(), sym2 = Symbol(), sym3 = Symbol();
+ var obj = {
+ 1: true,
+ A: true
+ };
+ obj.B = true;
+ obj[sym1] = true;
+ obj[2] = true;
+ obj[sym2] = true;
+ Object.defineProperty(obj, 'C', { value: true, enumerable: true });
+ Object.defineProperty(obj, sym3,{ value: true, enumerable: true });
+ Object.defineProperty(obj, 'D', { value: true, enumerable: true });
+
+ var result = Reflect.ownKeys(obj);
+ var l = result.length;
+ return result[l-3] === sym1 && result[l-2] === sym2 && result[l-1] === sym3;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ closure: true,
+ closure20190301: false,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ safari10: true,
+ firefox2: false,
+ firefox42: true,
+ opera10_50: false,
+ xs6: true,
+ ejs: true,
+ chrome49: true,
+ duktape2_0: false,
+ duktape2_2: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'Updated identifier syntax',
+ category: 'misc',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-names-and-keywords',
+ subtests: [
+ {
+ name: 'var ⸯ;',
+ exec() {
+ /*
+ try {
+ eval('var ⸯ');
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ es6tr: null,
+ tr: null,
+ babel6corejs2: null,
+ closure: false,
+ jsx: null,
+ typescript1corejs2: null,
+ es6shim: null,
+ konq4_14: null,
+ ie7: null,
+ ie10: false,
+ ie11: true,
+ edge14: true,
+ firefox1: null,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ chrome1: null,
+ chrome58: true,
+ safari1: false,
+ safari12_1: true,
+ safaritp: true,
+ rhino1_7_13: false,
+ xs6: null,
+ jxa: null,
+ node0_10: null,
+ duktape2_0: false,
+ android1_5: null,
+ ios4: null,
+ graalvm19: true,
+ jerryscript1_0: true,
+ jerryscript2_0: false,
+ jerryscript2_4_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ },
+ },
+ {
+ name: 'var 𐋀;',
+ exec() {
+ /*
+ var 𐋀;
+ return true;
+ */
+ },
+ res: {
+ es6tr: null,
+ tr: null,
+ babel6corejs2: null,
+ closure: false,
+ jsx: null,
+ typescript1corejs2: null,
+ es6shim: null,
+ konq4_14: null,
+ ie7: null,
+ ie10: false,
+ edge12: null,
+ edge14: true,
+ firefox1: null,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ chrome1: null,
+ chrome58: true,
+ safari1: false,
+ safari14: true,
+ webkit: false,
+ rhino1_7_13: false,
+ xs6: null,
+ jxa: null,
+ node0_10: null,
+ duktape2_0: false,
+ android1_5: null,
+ ios4: null,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_4_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'no escaped reserved words as identifiers',
+ exec() {
+ /*
+ var \u0061;
+ try {
+ eval('var v\\u0061r');
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ es6tr: true,
+ tr: true,
+ babel6corejs2: true,
+ closure: true,
+ jsx: true,
+ typescript1corejs2: true,
+ es6shim: null,
+ konq4_14: null,
+ ie7: null,
+ ie10: true,
+ firefox1: null,
+ firefox2: false,
+ firefox10: true,
+ opera10_50: false,
+ opera12_10: true,
+ chrome1: null,
+ chrome49: true,
+ safari1: null,
+ safari9: true,
+ rhino1_7_13: false,
+ xs6: true,
+ jxa: true,
+ node0_10: null,
+ duktape2_0: false,
+ android1_5: null,
+ ios4: null,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_15: true,
+ },
+ },
+ ],
+ },
+ {
+ name: 'miscellaneous',
+ category: 'misc',
+ significance: 'small',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-additions-and-changes-that-introduce-incompatibilities-with-prior-editions',
+ subtests: [
+ {
+ name: 'duplicate property names in strict mode',
+ exec() {
+ /*
+ 'use strict';
+ return this === void undefined && ({ a:1, a:1 }).a === 1;
+ */
+ },
+ res: {
+ ejs: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox34: true,
+ opera10_50: false,
+ chrome42: true,
+ safari9: true,
+ node4: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'no semicolon needed after do-while',
+ exec() {
+ /*
+ do {} while (false) return true;
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'no assignments allowed in for-in head in strict mode',
+ exec() {
+ /*
+ 'use strict';
+ try {
+ eval('for (var i = 0 in {}) {}');
+ }
+ catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ ejs: true,
+ babel6corejs2: true,
+ closure: true,
+ typescript1corejs2: true,
+ ie11: false,
+ edge15: true,
+ firefox2: false,
+ firefox52: true,
+ opera10_50: false,
+ chrome45: true,
+ safari9: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: false,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: "accessors aren't constructors",
+ exec() {
+ /*
+ var f = (Object.getOwnPropertyDescriptor({get a(){}}, 'a')).get;
+ try {
+ new f;
+ } catch(e) {
+ return true;
+ }
+ */
+ },
+ res: {
+ ie11: false,
+ edge12: true,
+ chrome42: true,
+ node4: true,
+ firefox2: false,
+ firefox41: true,
+ opera10_50: false,
+ safari10: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ reactnative0_70_3: false,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'Invalid Date',
+ exec() {
+ /*
+ return new Date(NaN) + "" === "Invalid Date";
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ es6shim: true,
+ ejs: true,
+ ie10: true,
+ firefox2: true,
+ chrome5: true,
+ safari3_1: true,
+ opera10_50: true,
+ opera12: true,
+ konq4_14: true,
+ rhino1_7_13: true,
+ node0_12: true,
+ android4_0: true,
+ xs6: true,
+ jxa: true,
+ duktape2_0: true,
+ nashorn1_8: true,
+ nashorn9: true,
+ nashorn10: true,
+ graalvm19: true,
+ jerryscript1_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ },
+ },
+ {
+ name: 'RegExp constructor can alter flags',
+ exec() {
+ /*
+ return new RegExp(/./im, "g").global === true;
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ejs: true,
+ es6shim: true,
+ ie11: false,
+ edge12: true,
+ firefox2: false,
+ firefox39: true,
+ opera10_50: false,
+ xs6: true,
+ chrome49: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: 'RegExp.prototype.toString generic and uses "flags" property',
+ exec() {
+ /*
+ return RegExp.prototype.toString.call({source: 'foo', flags: 'bar'}) === '/foo/bar';
+ */
+ },
+ res: {
+ babel6corejs2: babel.corejs,
+ typescript1corejs2: typescript.corejs,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox39: true,
+ opera10_50: false,
+ chrome50: true,
+ ejs: null,
+ xs6: null,
+ jxa: true,
+ safari10: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_2_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ rhino1_7_15: true,
+ },
+ },
+ {
+ name: 'built-in prototypes are not instances',
+ exec() {
+ /*
+ try {
+ RegExp.prototype.exec(); return false;
+ } catch(e) {}
+ try {
+ Date.prototype.valueOf(); return false;
+ } catch(e) {}
+
+ if (![Error, EvalError, RangeError, ReferenceError, SyntaxError, TypeError, URIError].every(function (E) {
+ return Object.prototype.toString.call(E.prototype) === '[object Object]';
+ })) {
+ return false;
+ }
+
+ return true;
+ */
+ },
+ res: {
+ xs6: false,
+ jxa: true,
+ ie11: false,
+ edge14: edge.experimental,
+ firefox2: false,
+ firefox53: true,
+ opera10_50: false,
+ chrome50: true,
+ safari10: true,
+ duktape2_0: false,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: false,
+ hermes0_12_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ {
+ name: "function 'length' is configurable",
+ exec() {
+ /*
+ var fn = function(a, b) {};
+
+ var desc = Object.getOwnPropertyDescriptor(fn, "length");
+ if (desc.configurable) {
+ Object.defineProperty(fn, "length", { value: 1 });
+ return fn.length === 1;
+ }
+
+ return false;
+ */
+ },
+ res: {
+ firefox2: false,
+ firefox37: true,
+ opera10_50: false,
+ chrome43: true,
+ ie11: false,
+ edge12: true,
+ node4: true,
+ xs6: true,
+ safari10: true,
+ jxa: true,
+ duktape2_0: true,
+ graalvm19: true,
+ jerryscript2_0: false,
+ jerryscript2_3_0: true,
+ hermes0_7_0: true,
+ reactnative0_70_3: true,
+ rhino1_7_13: false,
+ },
+ },
+ ],
+ },
+ {
+ name: 'HTML-style comments',
+ category: 'annex b',
+ significance: 'tiny',
+ spec: 'http://www.ecma-international.org/ecma-262/6.0/#sec-html-like-comments',
+ exec() {
+ /*
+ --> A comment
+